├── .gitattributes ├── .gitignore ├── CodeParser.Test ├── CodeParser.Test.csproj ├── Examples │ ├── HelloWorld.cs │ ├── HelloWorld.js │ ├── HelloWorld.py │ └── Helloworld.cpp ├── ParserHelper.cs ├── ParserTest │ ├── CSharpParserTest.cs │ ├── CodeParserTest.cs │ ├── CppParserTest.cs │ ├── JavaScriptParserTest.cs │ └── PythonParserTest.cs └── Program.cs ├── CodeParser.Viewer ├── App.config ├── CodeParser.Viewer.csproj ├── Model │ ├── SqlSyntaxError.cs │ └── TokenInfo.cs ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── Resources │ └── magic.ico ├── SqlSyntaxErrorListener.cs ├── frmMain.cs ├── frmMain.designer.cs ├── frmMain.resx └── packages.config ├── CodeParser.sln ├── CodeParser ├── CodeParser.csproj ├── Manager │ └── ParserManager.cs ├── Model │ └── ParserInfo.cs └── Parser │ ├── C │ ├── CBaseListener.cs │ ├── CLexer.cs │ ├── CListener.cs │ └── CParser.cs │ ├── CSharp │ ├── CSharpLexer.cs │ ├── CSharpLexerBase.cs │ ├── CSharpParser.cs │ ├── CSharpParserBase.cs │ ├── CSharpParserBaseListener.cs │ └── CSharpParserListener.cs │ ├── Cpp │ ├── CPP14BaseListener.cs │ ├── CPP14Lexer.cs │ ├── CPP14Listener.cs │ └── CPP14Parser.cs │ ├── Java │ ├── Java8Lexer.cs │ ├── Java8Parser.cs │ ├── Java8ParserBaseListener.cs │ ├── Java8ParserListener.cs │ ├── Java9BaseListener.cs │ ├── Java9Lexer.cs │ ├── Java9LexerBase.cs │ ├── Java9Listener.cs │ ├── Java9Parser.cs │ ├── Java9ParserBaseListener.cs │ └── Java9ParserListener.cs │ ├── JavaScript │ ├── JavaScriptLexer.cs │ ├── JavaScriptLexerBase.cs │ ├── JavaScriptParser.cs │ ├── JavaScriptParserBase.cs │ ├── JavaScriptParserBaseListener.cs │ └── JavaScriptParserListener.cs │ ├── LexerDispatchingErrorListener.cs │ ├── MySql │ ├── IMySqlRecognizerCommon.cs │ ├── MySqlBaseLexer.cs │ ├── MySqlBaseRecognizer.cs │ ├── MySqlLexer.cs │ ├── MySqlMode.cs │ ├── MySqlParser.cs │ ├── MySqlParserBaseListener.cs │ ├── MySqlParserListener.cs │ ├── MySqlParsersCommon.cs │ ├── MySqlRecognizerCommon.cs │ └── MySqlServerVersion.cs │ ├── ParserDispatchingErrorListener.cs │ ├── Php │ ├── PhpLexer.cs │ ├── PhpLexerBase.cs │ ├── PhpParser.cs │ ├── PhpParserBaseListener.cs │ └── PhpParserListener.cs │ ├── PlSql │ ├── PlSqlLexer.cs │ ├── PlSqlLexerBase.cs │ ├── PlSqlParser.cs │ ├── PlSqlParserBase.cs │ ├── PlSqlParserBaseListener.cs │ └── PlSqlParserListener.cs │ ├── PostgreSql │ ├── PostgreSqlLexer.cs │ ├── PostgreSqlLexerBase.cs │ ├── PostgreSqlParser.cs │ ├── PostgreSqlParserBase.cs │ ├── PostgreSqlParserBaseListener.cs │ └── PostgreSqlParserListener.cs │ ├── Python │ ├── Python3Lexer.cs │ ├── Python3LexerBase.cs │ ├── Python3Parser.cs │ ├── Python3ParserBaseListener.cs │ └── Python3ParserListener.cs │ ├── SQLite │ ├── SQLiteLexer.cs │ ├── SQLiteParser.cs │ ├── SQLiteParserBaseListener.cs │ └── SQLiteParserListener.cs │ └── TSql │ ├── TSqlLexer.cs │ ├── TSqlParser.cs │ ├── TSqlParserBaseListener.cs │ └── TSqlParserListener.cs └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | project.fragment.lock.json 46 | artifacts/ 47 | 48 | *_i.c 49 | *_p.c 50 | *_i.h 51 | *.ilk 52 | *.meta 53 | *.obj 54 | *.pch 55 | *.pdb 56 | *.pgc 57 | *.pgd 58 | *.rsp 59 | *.sbr 60 | *.tlb 61 | *.tli 62 | *.tlh 63 | *.tmp 64 | *.tmp_proj 65 | *.log 66 | *.vspscc 67 | *.vssscc 68 | .builds 69 | *.pidb 70 | *.svclog 71 | *.scc 72 | 73 | # Chutzpah Test files 74 | _Chutzpah* 75 | 76 | # Visual C++ cache files 77 | ipch/ 78 | *.aps 79 | *.ncb 80 | *.opendb 81 | *.opensdf 82 | *.sdf 83 | *.cachefile 84 | *.VC.db 85 | *.VC.VC.opendb 86 | 87 | # Visual Studio profiler 88 | *.psess 89 | *.vsp 90 | *.vspx 91 | *.sap 92 | 93 | # TFS 2012 Local Workspace 94 | $tf/ 95 | 96 | # Guidance Automation Toolkit 97 | *.gpState 98 | 99 | # ReSharper is a .NET coding add-in 100 | _ReSharper*/ 101 | *.[Rr]e[Ss]harper 102 | *.DotSettings.user 103 | 104 | # JustCode is a .NET coding add-in 105 | .JustCode 106 | 107 | # TeamCity is a build add-in 108 | _TeamCity* 109 | 110 | # DotCover is a Code Coverage Tool 111 | *.dotCover 112 | 113 | # NCrunch 114 | _NCrunch_* 115 | .*crunch*.local.xml 116 | nCrunchTemp_* 117 | 118 | # MightyMoose 119 | *.mm.* 120 | AutoTest.Net/ 121 | 122 | # Web workbench (sass) 123 | .sass-cache/ 124 | 125 | # Installshield output folder 126 | [Ee]xpress/ 127 | 128 | # DocProject is a documentation generator add-in 129 | DocProject/buildhelp/ 130 | DocProject/Help/*.HxT 131 | DocProject/Help/*.HxC 132 | DocProject/Help/*.hhc 133 | DocProject/Help/*.hhk 134 | DocProject/Help/*.hhp 135 | DocProject/Help/Html2 136 | DocProject/Help/html 137 | 138 | # Click-Once directory 139 | publish/ 140 | 141 | # Publish Web Output 142 | *.[Pp]ublish.xml 143 | *.azurePubxml 144 | # TODO: Comment the next line if you want to checkin your web deploy settings 145 | # but database connection strings (with potential passwords) will be unencrypted 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 150 | # checkin your Azure Web App publish settings, but sensitive information contained 151 | # in these scripts will be unencrypted 152 | PublishScripts/ 153 | 154 | # NuGet Packages 155 | *.nupkg 156 | # The packages folder can be ignored because of Package Restore 157 | **/packages/* 158 | # except build/, which is used as an MSBuild target. 159 | !**/packages/build/ 160 | # Uncomment if necessary however generally it will be regenerated when needed 161 | #!**/packages/repositories.config 162 | # NuGet v3's project.json files produces more ignoreable files 163 | *.nuget.props 164 | *.nuget.targets 165 | 166 | # Microsoft Azure Build Output 167 | csx/ 168 | *.build.csdef 169 | 170 | # Microsoft Azure Emulator 171 | ecf/ 172 | rcf/ 173 | 174 | # Windows Store app package directories and files 175 | AppPackages/ 176 | BundleArtifacts/ 177 | Package.StoreAssociation.xml 178 | _pkginfo.txt 179 | 180 | # Visual Studio cache files 181 | # files ending in .cache can be ignored 182 | *.[Cc]ache 183 | # but keep track of directories ending in .cache 184 | !*.[Cc]ache/ 185 | 186 | # Others 187 | ClientBin/ 188 | ~$* 189 | *~ 190 | *.dbmdl 191 | *.dbproj.schemaview 192 | *.jfm 193 | *.pfx 194 | *.publishsettings 195 | node_modules/ 196 | orleans.codegen.cs 197 | 198 | # Since there are multiple workflows, uncomment next line to ignore bower_components 199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 200 | #bower_components/ 201 | 202 | # RIA/Silverlight projects 203 | Generated_Code/ 204 | 205 | # Backup & report files from converting an old project file 206 | # to a newer Visual Studio version. Backup files are not needed, 207 | # because we have git ;-) 208 | _UpgradeReport_Files/ 209 | Backup*/ 210 | UpgradeLog*.XML 211 | UpgradeLog*.htm 212 | 213 | # SQL Server files 214 | *.mdf 215 | *.ldf 216 | 217 | # Business Intelligence projects 218 | *.rdl.data 219 | *.bim.layout 220 | *.bim_*.settings 221 | 222 | # Microsoft Fakes 223 | FakesAssemblies/ 224 | 225 | # GhostDoc plugin setting file 226 | *.GhostDoc.xml 227 | 228 | # Node.js Tools for Visual Studio 229 | .ntvs_analysis.dat 230 | 231 | # Visual Studio 6 build log 232 | *.plg 233 | 234 | # Visual Studio 6 workspace options file 235 | *.opt 236 | 237 | # Visual Studio LightSwitch build output 238 | **/*.HTMLClient/GeneratedArtifacts 239 | **/*.DesktopClient/GeneratedArtifacts 240 | **/*.DesktopClient/ModelManifest.xml 241 | **/*.Server/GeneratedArtifacts 242 | **/*.Server/ModelManifest.xml 243 | _Pvt_Extensions 244 | 245 | # Paket dependency manager 246 | .paket/paket.exe 247 | paket-files/ 248 | 249 | # FAKE - F# Make 250 | .fake/ 251 | 252 | # JetBrains Rider 253 | .idea/ 254 | *.sln.iml 255 | 256 | # CodeRush 257 | .cr/ 258 | 259 | # Python Tools for Visual Studio (PTVS) 260 | __pycache__/ 261 | *.pyc 262 | /CodeParser.Test/Examples/Tsql_view.sql 263 | /CodeParser.Test/ParserTest/TsqlParserTest.cs 264 | -------------------------------------------------------------------------------- /CodeParser.Test/CodeParser.Test.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | PreserveNewest 22 | 23 | 24 | PreserveNewest 25 | 26 | 27 | PreserveNewest 28 | 29 | 30 | PreserveNewest 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /CodeParser.Test/Examples/HelloWorld.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.IO; 6 | 7 | namespace Demo 8 | { 9 | public interface ISpeech 10 | { 11 | string Name { get; } 12 | void SayHello(string word); 13 | } 14 | 15 | public delegate void SayHelloHandler(string word); 16 | 17 | public class CSharpHelloWord : ISpeech 18 | { 19 | public event SayHelloHandler OnSayHello; 20 | 21 | public string owner; 22 | public string Owner 23 | { 24 | get { return this.owner; } 25 | set { this.owner = value; } 26 | } 27 | 28 | public void SayHello(string word) 29 | { 30 | Console.WriteLine(word); 31 | } 32 | } 33 | 34 | public enum SayMode 35 | { 36 | Default, 37 | Custom 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /CodeParser.Test/Examples/HelloWorld.js: -------------------------------------------------------------------------------- 1 | import { Helper } from '/modules/util.js'; 2 | 3 | var owner = ""; 4 | 5 | function test(word) { 6 | var helloWord = new helloWord(); 7 | helloWord.sayHello(word); 8 | } 9 | 10 | var helloWord = { 11 | owner: "", 12 | target: "", 13 | sayHello: function (word) { 14 | alert(word); 15 | } 16 | }; 17 | 18 | export function sayHello(word) { 19 | test("Hello"); 20 | } 21 | 22 | export { sayHello as say }; -------------------------------------------------------------------------------- /CodeParser.Test/Examples/HelloWorld.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | class HelloWorld(): 4 | owner = "" 5 | target = "" 6 | def sayHello(self, word): 7 | print(word) 8 | 9 | x = HelloWorld() 10 | 11 | x.sayHello("Hello") 12 | -------------------------------------------------------------------------------- /CodeParser.Test/Examples/Helloworld.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | main() 7 | { 8 | cout << "Hello World!"; 9 | return 0; 10 | } 11 | 12 | class HelloWorld 13 | { 14 | public: 15 | string owner, target; 16 | int age; 17 | 18 | 19 | public: 20 | void sayHello(string word) 21 | { 22 | cout << word; 23 | } 24 | 25 | void test() 26 | { 27 | cout << "Test"; 28 | } 29 | }; 30 | 31 | -------------------------------------------------------------------------------- /CodeParser.Test/ParserHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Reflection; 4 | 5 | namespace CodeParser.Test 6 | { 7 | public class ParserHelper 8 | { 9 | 10 | public static CodeParserTest GetParserTest(string language) 11 | { 12 | var assembly = Assembly.GetExecutingAssembly(); 13 | var typeArray = assembly.ExportedTypes; 14 | 15 | var types = (from type in typeArray 16 | where type.IsSubclassOf(typeof(CodeParserTest)) 17 | select type).ToList(); 18 | 19 | foreach (var type in types) 20 | { 21 | CodeParserTest codeParserTest = (CodeParserTest)Activator.CreateInstance(type); 22 | 23 | if (codeParserTest.Language == language) 24 | { 25 | return codeParserTest; 26 | } 27 | } 28 | 29 | return null; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /CodeParser.Test/ParserTest/CSharpParserTest.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using Antlr4.Runtime.Tree; 3 | using System; 4 | using System.IO; 5 | using System.Linq; 6 | using static CSharpParser; 7 | 8 | namespace CodeParser.Test 9 | { 10 | public class CSharpParserTest : CodeParserTest 11 | { 12 | public override string Language => "C#"; 13 | 14 | public override void Parse(FileInfo file) 15 | { 16 | Lexer lexer = new CSharpLexer(CharStreams.fromPath(file.FullName)); 17 | 18 | CommonTokenStream tokens = new CommonTokenStream(lexer); 19 | 20 | CSharpParser parser = new CSharpParser(tokens); 21 | 22 | ParserRuleContext context = parser.compilation_unit(); 23 | 24 | var children = context.children; 25 | 26 | foreach (IParseTree child in children) 27 | { 28 | this.ParseNode(child); 29 | } 30 | } 31 | 32 | private void ParseNode(IParseTree node) 33 | { 34 | if (node is Using_directivesContext) 35 | { 36 | Using_directivesContext usingContext = node as Using_directivesContext; 37 | UsingNamespaceDirectiveContext[] usingNamespaces = usingContext.GetRuleContexts(); 38 | foreach (UsingNamespaceDirectiveContext ns in usingNamespaces) 39 | { 40 | string name = ns.namespace_or_type_name().GetText(); 41 | this.WriteKeyValue("Using", name); 42 | } 43 | } 44 | else if (node is Namespace_member_declarationsContext) 45 | { 46 | Namespace_member_declarationsContext nsMemberContext = node as Namespace_member_declarationsContext; 47 | 48 | Namespace_member_declarationContext[] members = nsMemberContext.namespace_member_declaration(); 49 | 50 | foreach (Namespace_member_declarationContext member in members) 51 | { 52 | Type memberType = member.children[0].GetType(); 53 | 54 | Namespace_declarationContext[] nses = member.GetRuleContexts(); 55 | Type_declarationContext[] types = member.GetRuleContexts(); 56 | 57 | foreach (Namespace_declarationContext ns in nses) 58 | { 59 | string name = this.GetNodeName(ns.qualified_identifier().identifier().First()); 60 | 61 | this.WriteKeyValue("Namespace", name); 62 | 63 | var childMembers = ns.namespace_body().namespace_member_declarations().namespace_member_declaration(); 64 | 65 | foreach (var childMember in childMembers) 66 | { 67 | var childMemberDeclaration = childMember.children[0]; 68 | 69 | if (childMemberDeclaration is Type_declarationContext) 70 | { 71 | this.ParseTypeDeclaration(childMemberDeclaration as Type_declarationContext); 72 | } 73 | } 74 | } 75 | 76 | foreach (Type_declarationContext t in types) 77 | { 78 | this.ParseTypeDeclaration(t); 79 | } 80 | } 81 | } 82 | } 83 | 84 | private void ParseTypeDeclaration(Type_declarationContext node) 85 | { 86 | Class_definitionContext classContext = node.class_definition(); 87 | Interface_definitionContext interfaceContext = node.interface_definition(); 88 | Delegate_definitionContext delegateContext = node.delegate_definition(); 89 | Enum_definitionContext enumContext = node.enum_definition(); 90 | 91 | bool isClass = classContext != null; 92 | bool isInterface = interfaceContext != null; 93 | bool isDelegate = delegateContext != null; 94 | bool isEnum = enumContext != null; 95 | 96 | string type = ""; 97 | string name = ""; 98 | if (isClass) 99 | { 100 | type = "Class"; 101 | name = this.GetNodeName(classContext.identifier()); 102 | } 103 | else if (isInterface) 104 | { 105 | type = "Interface"; 106 | name = this.GetNodeName(interfaceContext.identifier()); 107 | } 108 | else if (isDelegate) 109 | { 110 | type = "Delegate"; 111 | name = this.GetNodeName(delegateContext.identifier()); 112 | } 113 | else if (isEnum) 114 | { 115 | type = "Enum"; 116 | name = this.GetNodeName(enumContext.identifier()); 117 | } 118 | 119 | if (!string.IsNullOrEmpty(name)) 120 | { 121 | this.WriteLine(); 122 | this.WriteKeyValue(type, name); 123 | } 124 | 125 | if (isClass) 126 | { 127 | this.WriteBeginBrace(); 128 | this.ParseClassDeclaration(classContext); 129 | this.WriteEndBrace(); 130 | } 131 | else if (isInterface) 132 | { 133 | this.WriteBeginBrace(); 134 | this.ParseInterfaceDeclaration(interfaceContext); 135 | this.WriteEndBrace(); 136 | } 137 | } 138 | 139 | private void ParseClassDeclaration(Class_definitionContext node) 140 | { 141 | var members = node.class_body().class_member_declarations().class_member_declaration(); 142 | foreach (var member in members) 143 | { 144 | Common_member_declarationContext child = member.GetRuleContext(0); 145 | 146 | if (child is Common_member_declarationContext) 147 | { 148 | Common_member_declarationContext commonMemberContext = child as Common_member_declarationContext; 149 | 150 | Event_declarationContext eventContext = commonMemberContext.event_declaration(); 151 | Typed_member_declarationContext typeMemberContext = commonMemberContext.typed_member_declaration(); 152 | Method_declarationContext methodContext = commonMemberContext.method_declaration(); 153 | 154 | string type = ""; 155 | string name = ""; 156 | 157 | if (eventContext != null) 158 | { 159 | type = "Event"; 160 | name = eventContext.variable_declarators().GetText(); 161 | } 162 | 163 | if (typeMemberContext != null) 164 | { 165 | Field_declarationContext field = typeMemberContext.field_declaration(); 166 | Property_declarationContext property = typeMemberContext.property_declaration(); 167 | 168 | if (field != null) 169 | { 170 | type = "Field"; 171 | name = field.variable_declarators().GetText(); 172 | } 173 | else if (property != null) 174 | { 175 | type = "Property"; 176 | name = property.member_name().GetText(); 177 | } 178 | } 179 | else if (methodContext != null) 180 | { 181 | type = "Method"; 182 | name = methodContext.method_member_name().GetText(); 183 | } 184 | 185 | if (!string.IsNullOrEmpty(name)) 186 | { 187 | this.WriteKeyValue(type, name); 188 | } 189 | } 190 | } 191 | } 192 | 193 | private void ParseInterfaceDeclaration(Interface_definitionContext node) 194 | { 195 | var members = node.class_body().class_member_declarations(); 196 | 197 | foreach (var member in members.children) 198 | { 199 | if (member is Interface_member_declarationContext) 200 | { 201 | Interface_member_declarationContext memberContext = member as Interface_member_declarationContext; 202 | Type_Context typeContext = memberContext.type_(); 203 | 204 | bool isProperty = typeContext != null; 205 | 206 | IdentifierContext identifierContext = memberContext.identifier(); 207 | 208 | if (identifierContext != null) 209 | { 210 | string name = this.GetNodeName(identifierContext); 211 | this.WriteKeyValue((isProperty ? "Property" : "Method"), name); 212 | } 213 | } 214 | } 215 | } 216 | 217 | protected string GetNodeName(IdentifierContext node) 218 | { 219 | return node.GetText(); 220 | } 221 | } 222 | } 223 | -------------------------------------------------------------------------------- /CodeParser.Test/ParserTest/CodeParserTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace CodeParser.Test 5 | { 6 | public abstract class CodeParserTest 7 | { 8 | public virtual string SubFolder { get; set; } 9 | public abstract string Language { get; } 10 | 11 | protected int indent = 0; 12 | 13 | public void Parse(ParserInfo info) 14 | { 15 | DirectoryInfo di = new DirectoryInfo("Examples" + (!string.IsNullOrEmpty(this.SubFolder) ? ("/" + this.SubFolder) : "")); 16 | 17 | FileInfo[] files = di.GetFiles("*" + info.FileExtension); 18 | 19 | foreach (var file in files) 20 | { 21 | this.WriteLine(); 22 | this.WriteLine($"{file.Name}"); 23 | this.WriteBeginBoundaryLine(); 24 | this.Parse(file); 25 | this.WriteEndBoundaryLine(); 26 | } 27 | } 28 | 29 | protected void WriteLine() 30 | { 31 | this.WriteLine(""); 32 | } 33 | 34 | protected void WriteBeginBoundaryLine() 35 | { 36 | this.WriteLine(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); 37 | } 38 | 39 | protected void WriteEndBoundaryLine() 40 | { 41 | this.WriteLine("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"); 42 | } 43 | 44 | protected void WriteBeginBrace(int indent = 0) 45 | { 46 | this.WriteLine(this.GetIndent(indent) + "{"); 47 | } 48 | 49 | protected void WriteEndBrace(int indent = 0) 50 | { 51 | this.WriteLine(this.GetIndent(indent) + "}"); 52 | } 53 | 54 | public virtual void Parse(FileInfo file) { } 55 | 56 | protected void WriteKeyValue(string key, string value, int indent=0) 57 | { 58 | this.WriteLine(this.GetIndent(indent) + $"{key}:{value}"); 59 | } 60 | 61 | protected void WriteLine(string text, int indent=0) 62 | { 63 | Console.WriteLine(this.GetIndent(indent) + text); 64 | } 65 | 66 | protected void Write(string text, int indent = 0) 67 | { 68 | Console.Write(this.GetIndent(indent) + text); 69 | } 70 | 71 | private string GetIndent(int indent) 72 | { 73 | return "".PadLeft(indent, ' '); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /CodeParser.Test/ParserTest/CppParserTest.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using Antlr4.Runtime.Tree; 3 | using System.IO; 4 | using static CPP14Parser; 5 | 6 | namespace CodeParser.Test 7 | { 8 | public class CppParserTest : CodeParserTest 9 | { 10 | public override string Language => "C++"; 11 | 12 | public override void Parse(FileInfo file) 13 | { 14 | Lexer lexer = new CPP14Lexer(CharStreams.fromPath(file.FullName)); 15 | 16 | CommonTokenStream tokens = new CommonTokenStream(lexer); 17 | 18 | CPP14Parser parser = new CPP14Parser(tokens); 19 | 20 | ParserRuleContext context = parser.translationunit(); 21 | 22 | var children = context.children; 23 | 24 | foreach (IParseTree child in children) 25 | { 26 | this.ParseNode(child); 27 | } 28 | } 29 | 30 | private void ParseNode(IParseTree node) 31 | { 32 | if (node is DeclarationseqContext) 33 | { 34 | DeclarationseqContext declarationseqContext = node as DeclarationseqContext; 35 | this.ParseDeclarationseq(declarationseqContext); 36 | } 37 | } 38 | 39 | private void ParseDeclarationseq(DeclarationseqContext node) 40 | { 41 | DeclarationseqContext declareSq = node.declarationseq(); 42 | DeclarationContext declare = node.declaration(); 43 | 44 | if (declareSq != null) 45 | { 46 | this.ParseDeclarationseq(declareSq); 47 | } 48 | 49 | if (declare != null) 50 | { 51 | AttributedeclarationContext attribute = declare.attributedeclaration(); 52 | FunctiondefinitionContext function = declare.functiondefinition(); 53 | BlockdeclarationContext block = declare.blockdeclaration(); 54 | 55 | if (block != null) 56 | { 57 | UsingdirectiveContext usingDirective = block.usingdirective(); 58 | SimpledeclarationContext simpleDeclaration = block.simpledeclaration(); 59 | 60 | if (usingDirective != null) 61 | { 62 | string name = usingDirective.namespacename().GetText(); 63 | 64 | this.WriteKeyValue("Using", name); 65 | } 66 | else if (simpleDeclaration != null) 67 | { 68 | DeclspecifierseqContext[] decls = simpleDeclaration.GetRuleContexts(); 69 | 70 | foreach (DeclspecifierseqContext decl in decls) 71 | { 72 | DeclspecifierContext declSpec = decl.declspecifier(); 73 | TypespecifierContext typeSpec = declSpec.typespecifier(); 74 | 75 | if (typeSpec != null) 76 | { 77 | ClassspecifierContext classSpec = typeSpec.classspecifier(); 78 | EnumspecifierContext enumSpec = typeSpec.enumspecifier(); 79 | 80 | if (classSpec != null) 81 | { 82 | string className = classSpec.classhead().classheadname().GetText(); 83 | 84 | this.WriteLine(); 85 | this.WriteKeyValue("Class", className); 86 | this.WriteBeginBrace(); 87 | 88 | MemberspecificationContext[] members = classSpec.GetRuleContexts(); 89 | 90 | foreach (MemberspecificationContext member in members) 91 | { 92 | MemberspecificationContext[] memberSpecs = member.GetRuleContexts(); 93 | 94 | foreach (MemberspecificationContext memberSpec in memberSpecs) 95 | { 96 | MemberdeclarationContext memberDeclaration = memberSpec.memberdeclaration(); 97 | MemberspecificationContext memberSpecDeclaration = memberSpec.memberspecification(); 98 | 99 | this.ParseMemberDeclaration(memberDeclaration); 100 | this.ParseMemberSpecification(memberSpecDeclaration); 101 | } 102 | } 103 | 104 | this.WriteEndBrace(); 105 | } 106 | } 107 | } 108 | } 109 | } 110 | else if (function != null) 111 | { 112 | this.ParseFunction(function); 113 | } 114 | } 115 | } 116 | 117 | private void ParseFunction(FunctiondefinitionContext node) 118 | { 119 | PtrdeclaratorContext[] ptrs = node.declarator().GetRuleContexts(); 120 | 121 | foreach (PtrdeclaratorContext ptr in ptrs) 122 | { 123 | NoptrdeclaratorContext noptr = ptr.noptrdeclarator(); 124 | string name = noptr.noptrdeclarator().GetText(); 125 | 126 | this.WriteKeyValue("Function", name); 127 | } 128 | } 129 | 130 | private void ParseMemberDeclaration(MemberdeclarationContext node) 131 | { 132 | if (node != null) 133 | { 134 | MemberspecificationContext[] memberSpecs = node.GetRuleContexts(); 135 | 136 | MemberdeclaratorlistContext[] fields = node.GetRuleContexts(); 137 | FunctiondefinitionContext[] funcs = node.GetRuleContexts(); 138 | 139 | if (fields != null) 140 | { 141 | foreach (MemberdeclaratorlistContext field in fields) 142 | { 143 | foreach (string name in field.GetText().Split(',')) 144 | { 145 | this.WriteKeyValue("Field", name); 146 | } 147 | } 148 | } 149 | 150 | if (funcs != null) 151 | { 152 | foreach (FunctiondefinitionContext func in funcs) 153 | { 154 | this.ParseFunction(func); 155 | } 156 | } 157 | } 158 | } 159 | 160 | private void ParseMemberSpecification(MemberspecificationContext node) 161 | { 162 | if (node != null) 163 | { 164 | MemberdeclarationContext[] members = node.GetRuleContexts(); 165 | MemberspecificationContext[] memberSpecs = node.GetRuleContexts(); 166 | 167 | foreach (MemberdeclarationContext member in members) 168 | { 169 | this.ParseMemberDeclaration(member); 170 | } 171 | 172 | foreach (MemberspecificationContext memberSpec in memberSpecs) 173 | { 174 | this.ParseMemberSpecification(memberSpec); 175 | } 176 | } 177 | } 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /CodeParser.Test/ParserTest/JavaScriptParserTest.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using Antlr4.Runtime.Tree; 3 | using System.IO; 4 | using System.Linq; 5 | using static JavaScriptParser; 6 | 7 | namespace CodeParser.Test 8 | { 9 | public class JavaScriptParserTest : CodeParserTest 10 | { 11 | public override string Language => "JavaScript"; 12 | 13 | public override void Parse(FileInfo file) 14 | { 15 | Lexer lexer = new JavaScriptLexer(CharStreams.fromPath(file.FullName)); 16 | 17 | CommonTokenStream tokens = new CommonTokenStream(lexer); 18 | 19 | JavaScriptParser parser = new JavaScriptParser(tokens); 20 | 21 | ParserRuleContext context = parser.program(); 22 | 23 | var children = context.children; 24 | 25 | foreach (IParseTree child in children) 26 | { 27 | this.ParseNode(child); 28 | } 29 | } 30 | 31 | private void ParseNode(IParseTree node) 32 | { 33 | if (node is SourceElementsContext) 34 | { 35 | SourceElementsContext elementsContext = node as SourceElementsContext; 36 | SourceElementContext[] srcElements = elementsContext.sourceElement(); 37 | foreach (SourceElementContext srcElement in srcElements) 38 | { 39 | StatementContext statementContext = srcElement.statement(); 40 | VariableStatementContext varStatementContext = statementContext.variableStatement(); 41 | FunctionDeclarationContext functionContext = statementContext.functionDeclaration(); 42 | ImportStatementContext importContext = statementContext.importStatement(); 43 | ExportStatementContext exportContext = statementContext.exportStatement(); 44 | 45 | if (varStatementContext != null) 46 | { 47 | VariableDeclarationListContext variableListContex = varStatementContext.variableDeclarationList(); 48 | 49 | if (variableListContex != null) 50 | { 51 | var variables = variableListContex.children; 52 | 53 | foreach (var variable in variables) 54 | { 55 | if (variable is VariableDeclarationContext) 56 | { 57 | VariableDeclarationContext declarationContext = variable as VariableDeclarationContext; 58 | string name = declarationContext.assignable().GetText(); 59 | 60 | ObjectLiteralExpressionContext[] exps = declarationContext.GetRuleContexts(); 61 | 62 | if (exps == null || exps.Length == 0) 63 | { 64 | this.WriteKeyValue("Field", name); 65 | } 66 | else 67 | { 68 | this.WriteKeyValue("Class", name); 69 | this.WriteBeginBrace(); 70 | 71 | foreach (ObjectLiteralExpressionContext exp in exps) 72 | { 73 | ObjectLiteralContext literalContext = exp.objectLiteral(); 74 | PropertyAssignmentContext[] properties = literalContext.propertyAssignment(); 75 | 76 | foreach (PropertyAssignmentContext property in properties) 77 | { 78 | PropertyNameContext propertyNameContext = property.GetRuleContext(0); 79 | FunctionExpressionContext funcExpContext = property.GetRuleContext(0); 80 | 81 | bool isFunction = funcExpContext != null; 82 | 83 | string propertyName = propertyNameContext.identifierName().GetText(); 84 | 85 | this.WriteKeyValue(isFunction ? "Function" : "Property", propertyName); 86 | } 87 | } 88 | 89 | this.WriteEndBrace(); 90 | } 91 | } 92 | } 93 | } 94 | } 95 | else if (functionContext != null) 96 | { 97 | string name = functionContext.identifier().GetText(); 98 | this.WriteKeyValue("Function", name); 99 | } 100 | else if (importContext != null) 101 | { 102 | ImportFromBlockContext fromContext = importContext.importFromBlock(); 103 | ModuleItemsContext[] moduleItems = fromContext.GetRuleContexts(); 104 | foreach (ModuleItemsContext module in moduleItems) 105 | { 106 | AliasNameContext[] aliasNames = module.aliasName(); 107 | foreach (AliasNameContext aliasName in aliasNames) 108 | { 109 | string name = aliasName.identifierName().LastOrDefault().GetText(); 110 | this.WriteKeyValue("Import", name); 111 | } 112 | } 113 | } 114 | else if (exportContext != null) 115 | { 116 | DeclarationContext[] declarations = exportContext.GetRuleContexts(); 117 | ExportFromBlockContext[] exportBlocks = exportContext.GetRuleContexts(); 118 | 119 | foreach (DeclarationContext declaration in declarations) 120 | { 121 | FunctionDeclarationContext funcContext = declaration.functionDeclaration(); 122 | 123 | if (funcContext != null) 124 | { 125 | string name = funcContext.identifier().GetText(); 126 | 127 | this.WriteKeyValue("Export", name); 128 | } 129 | } 130 | 131 | foreach (ExportFromBlockContext exportBlock in exportBlocks) 132 | { 133 | ModuleItemsContext[] moduleItems = exportBlock.GetRuleContexts(); 134 | foreach (ModuleItemsContext module in moduleItems) 135 | { 136 | AliasNameContext[] aliasNames = module.aliasName(); 137 | foreach (AliasNameContext aliasName in aliasNames) 138 | { 139 | IdentifierNameContext[] identifierNames = aliasName.identifierName(); 140 | string name = identifierNames.LastOrDefault().identifier().GetText(); 141 | this.WriteKeyValue("Export", name); 142 | } 143 | } 144 | } 145 | } 146 | } 147 | } 148 | } 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /CodeParser.Test/ParserTest/PythonParserTest.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using Antlr4.Runtime.Tree; 3 | using System.IO; 4 | using System.Linq; 5 | using static Python3Parser; 6 | 7 | namespace CodeParser.Test 8 | { 9 | public class PythonParserTest : CodeParserTest 10 | { 11 | public override string Language => "Python3"; 12 | 13 | public override void Parse(FileInfo file) 14 | { 15 | Lexer lexer = new Python3Lexer(CharStreams.fromPath(file.FullName)); 16 | 17 | CommonTokenStream tokens = new CommonTokenStream(lexer); 18 | 19 | Python3Parser parser = new Python3Parser(tokens); 20 | 21 | ParserRuleContext context = parser.file_input(); 22 | 23 | var children = context.children; 24 | 25 | foreach (IParseTree child in children) 26 | { 27 | this.ParseNode(child); 28 | } 29 | } 30 | 31 | private void ParseNode(IParseTree node) 32 | { 33 | if (node is StmtContext stmtContext) 34 | { 35 | Compound_stmtContext compound_Stmt = stmtContext.compound_stmt(); 36 | 37 | if (compound_Stmt != null) 38 | { 39 | ClassdefContext[] classdefs = compound_Stmt.GetRuleContexts(); 40 | 41 | foreach (ClassdefContext classdef in classdefs) 42 | { 43 | string name = classdef.NAME().GetText(); 44 | 45 | this.WriteLine(); 46 | this.WriteKeyValue("Class", name); 47 | 48 | this.WriteBeginBrace(); 49 | 50 | this.ParseClassContext(classdef); 51 | 52 | this.WriteEndBrace(); 53 | } 54 | } 55 | } 56 | } 57 | 58 | private void ParseClassContext(ClassdefContext node) 59 | { 60 | var suits = node.GetRuleContexts(); 61 | 62 | foreach (SuiteContext suit in suits) 63 | { 64 | var stmts = suit.stmt(); 65 | 66 | foreach (StmtContext stmt in stmts) 67 | { 68 | Simple_stmtContext simple_Stmt = stmt.simple_stmt(); 69 | Compound_stmtContext compound_Stmt = stmt.compound_stmt(); 70 | 71 | if (compound_Stmt != null) 72 | { 73 | var funcs = compound_Stmt.GetRuleContexts(); 74 | 75 | foreach (FuncdefContext func in funcs) 76 | { 77 | string name = func.NAME().GetText(); 78 | 79 | this.WriteKeyValue("Method", name); 80 | } 81 | } 82 | else if (simple_Stmt != null) 83 | { 84 | var exprs = simple_Stmt.GetRuleContexts(); 85 | 86 | foreach (var expr in exprs) 87 | { 88 | Testlist_star_exprContext[] ss = expr.GetRuleContexts(); 89 | 90 | string name = ss.FirstOrDefault()?.GetText(); 91 | 92 | if (!string.IsNullOrEmpty(name)) 93 | { 94 | this.WriteKeyValue("Field", name); 95 | } 96 | } 97 | } 98 | } 99 | } 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /CodeParser.Test/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CodeParser.Test 4 | { 5 | class Program 6 | { 7 | static void Main(string[] args) 8 | { 9 | Parse("Python3"); 10 | Parse("C#"); 11 | Parse("JavaScript"); 12 | Parse("C++"); 13 | 14 | Console.ReadLine(); 15 | } 16 | 17 | static void Parse(string language) 18 | { 19 | CodeParserTest codeParserTest = ParserHelper.GetParserTest(language); 20 | if (codeParserTest != null) 21 | { 22 | ParserInfo info = ParserManager.GetParserInfoByLanguage(language); 23 | 24 | if(info!=null) 25 | { 26 | codeParserTest.Parse(info); 27 | } 28 | else 29 | { 30 | Console.WriteLine($"Can't get ParserInfo for language \"{language}\"."); 31 | } 32 | } 33 | else 34 | { 35 | Console.WriteLine($"There's no parser test class for language \"{language}\"."); 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /CodeParser.Viewer/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /CodeParser.Viewer/CodeParser.Viewer.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {8E724F0A-1E47-45EF-918F-ED468F046289} 8 | WinExe 9 | CodeParser.Viewer 10 | CodeParser.Viewer 11 | v4.6.1 12 | 512 13 | true 14 | true 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | Resources\magic.ico 37 | 38 | 39 | 40 | ..\packages\Antlr4.Runtime.Standard.4.10.1\lib\netstandard2.0\Antlr4.Runtime.Standard.dll 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | Form 57 | 58 | 59 | frmMain.cs 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | frmMain.cs 68 | 69 | 70 | ResXFileCodeGenerator 71 | Resources.Designer.cs 72 | Designer 73 | 74 | 75 | True 76 | Resources.resx 77 | True 78 | 79 | 80 | 81 | SettingsSingleFileGenerator 82 | Settings.Designer.cs 83 | 84 | 85 | True 86 | Settings.settings 87 | True 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | {fd9c0211-571b-497b-88b4-fc145e07f03c} 99 | CodeParser 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /CodeParser.Viewer/Model/SqlSyntaxError.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Text; 3 | 4 | namespace CodeParser.Viewer 5 | { 6 | public class SqlSyntaxError 7 | { 8 | public List Items = new List(); 9 | 10 | public override string ToString() 11 | { 12 | StringBuilder sb = new StringBuilder(); 13 | 14 | foreach(SqlSyntaxErrorItem item in this.Items) 15 | { 16 | sb.AppendLine($"{item.Text}(Line={item.Line},Column={item.Column},StartIndex={item.StartIndex},StopIndex={item.StopIndex}):{item.Message};"); 17 | } 18 | 19 | return sb.ToString(); 20 | } 21 | } 22 | 23 | public class SqlSyntaxErrorItem 24 | { 25 | public int Line { get; set; } 26 | public int Column { get; set; } 27 | public int StartIndex { get; set; } 28 | public int StopIndex { get; set; } 29 | public string Text { get; set; } 30 | public string Message { get; set; } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /CodeParser.Viewer/Model/TokenInfo.cs: -------------------------------------------------------------------------------- 1 | namespace CodeParser.Viewer 2 | { 3 | public class TokenInfo 4 | { 5 | public int? StartIndex { get; set; } 6 | public int? StopIndex { get; set; } 7 | public int? ChildCount { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /CodeParser.Viewer/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.Windows.Forms; 6 | 7 | namespace CodeParser.Viewer 8 | { 9 | static class Program 10 | { 11 | /// 12 | /// 应用程序的主入口点。 13 | /// 14 | [STAThread] 15 | static void Main() 16 | { 17 | Application.EnableVisualStyles(); 18 | Application.SetCompatibleTextRenderingDefault(false); 19 | Application.Run(new frmMain()); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /CodeParser.Viewer/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的一般信息由以下 6 | // 控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("CodeParser.Viewer")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("CodeParser.Viewer")] 13 | [assembly: AssemblyCopyright("Copyright © 2020")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // 将 ComVisible 设置为 false 会使此程序集中的类型 18 | //对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 19 | //请将此类型的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("8e724f0a-1e47-45ef-918f-ed468f046289")] 24 | 25 | // 程序集的版本信息由下列四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | // 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号 33 | // 方法是按如下所示使用“*”: : 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /CodeParser.Viewer/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // 此代码由工具生成。 4 | // 运行时版本:4.0.30319.42000 5 | // 6 | // 对此文件的更改可能会导致不正确的行为,并且如果 7 | // 重新生成代码,这些更改将会丢失。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace CodeParser.Viewer.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// 一个强类型的资源类,用于查找本地化的字符串等。 17 | /// 18 | // 此类是由 StronglyTypedResourceBuilder 19 | // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 20 | // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen 21 | // (以 /str 作为命令选项),或重新生成 VS 项目。 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// 返回此类使用的缓存的 ResourceManager 实例。 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("CodeParser.Viewer.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// 重写当前线程的 CurrentUICulture 属性 51 | /// 重写当前线程的 CurrentUICulture 属性。 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// 查找类似于 (图标) 的 System.Drawing.Icon 类型的本地化资源。 65 | /// 66 | internal static System.Drawing.Icon magic { 67 | get { 68 | object obj = ResourceManager.GetObject("magic", resourceCulture); 69 | return ((System.Drawing.Icon)(obj)); 70 | } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /CodeParser.Viewer/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | ..\Resources\magic.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 123 | 124 | -------------------------------------------------------------------------------- /CodeParser.Viewer/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace CodeParser.Viewer.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /CodeParser.Viewer/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CodeParser.Viewer/Resources/magic.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/victor-wiki/CodeParser/f1e7ea683c2b20b5365926a2f21fdf3360a75d3d/CodeParser.Viewer/Resources/magic.ico -------------------------------------------------------------------------------- /CodeParser.Viewer/SqlSyntaxErrorListener.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using System.IO; 3 | 4 | namespace CodeParser.Viewer 5 | { 6 | public class SqlSyntaxErrorListener : BaseErrorListener 7 | { 8 | public bool HasError => this.Error != null && this.Error.Items.Count > 0; 9 | public SqlSyntaxError Error { get; private set; } 10 | 11 | public override void SyntaxError(TextWriter output, IRecognizer recognizer, IToken offendingSymbol, int line, int charPositionInLine, string msg, RecognitionException e) 12 | { 13 | if (this.Error == null) 14 | { 15 | this.Error = new SqlSyntaxError(); 16 | } 17 | 18 | if (offendingSymbol is CommonToken token) 19 | { 20 | SqlSyntaxErrorItem errorItem = new SqlSyntaxErrorItem(); 21 | 22 | errorItem.StartIndex = token.StartIndex; 23 | errorItem.StopIndex = token.StopIndex; 24 | errorItem.Line = token.Line; 25 | errorItem.Column = token.Column + 1; 26 | errorItem.Text = token.Text; 27 | errorItem.Message = msg; 28 | 29 | this.Error.Items.Add(errorItem); 30 | } 31 | 32 | base.SyntaxError(output, recognizer, offendingSymbol, line, charPositionInLine, msg, e); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /CodeParser.Viewer/frmMain.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.IO; 7 | using System.Linq; 8 | using System.Reflection; 9 | using System.Text; 10 | using System.Text.RegularExpressions; 11 | using System.Threading.Tasks; 12 | using System.Windows.Forms; 13 | using Antlr4.Runtime; 14 | using Antlr4.Runtime.Tree; 15 | 16 | namespace CodeParser.Viewer 17 | { 18 | public partial class frmMain : Form 19 | { 20 | private string coderPaserDllName = "CodeParser.dll"; 21 | private Assembly assembly = null; 22 | private List parserTypes = new List(); 23 | private Parser parser = null; 24 | private Color selectionBackColor = ColorTranslator.FromHtml("#0078D7"); 25 | private Dictionary dictTokenInfo = new Dictionary(); 26 | private SqlSyntaxError error; 27 | 28 | public delegate void AddNodeDelegate(TreeNode node); 29 | 30 | private static List ignoreMethods = new List() 31 | { 32 | "Eof" 33 | }; 34 | 35 | public frmMain() 36 | { 37 | RichTextBox.CheckForIllegalCrossThreadCalls = false; 38 | TreeView.CheckForIllegalCrossThreadCalls = false; 39 | TextBox.CheckForIllegalCrossThreadCalls = false; 40 | Label.CheckForIllegalCrossThreadCalls = false; 41 | 42 | InitializeComponent(); 43 | } 44 | 45 | private void frmMain_Load(object sender, EventArgs e) 46 | { 47 | this.InitControls(); 48 | } 49 | 50 | private void InitControls() 51 | { 52 | this.LoadParsers(); 53 | 54 | this.cboParser.SelectedIndex = -1; 55 | } 56 | 57 | private bool IsSqlParser() 58 | { 59 | string parserName = this.cboParser.Text; 60 | 61 | if (!string.IsNullOrEmpty(parserName)) 62 | { 63 | if (parserName == nameof(MySqlParser) || 64 | parserName == nameof(TSqlParser) || 65 | parserName == nameof(PlSqlParser) || 66 | parserName == nameof(PostgreSqlParser) || 67 | parserName == nameof(SQLiteParser) 68 | ) 69 | { 70 | return true; 71 | } 72 | } 73 | return false; 74 | } 75 | 76 | private void LoadParsers() 77 | { 78 | this.assembly = Assembly.LoadFrom(this.coderPaserDllName); 79 | var typeArray = this.assembly.ExportedTypes; 80 | 81 | this.parserTypes = (from type in typeArray 82 | where type.IsSubclassOf(typeof(Parser)) && !type.IsAbstract 83 | orderby type.Name 84 | select type).ToList(); 85 | 86 | this.cboParser.DataSource = this.parserTypes; 87 | this.cboParser.DisplayMember = "Name"; 88 | this.cboParser.ValueMember = "Name"; 89 | } 90 | 91 | private Type GetLexerType(string name) 92 | { 93 | return (from type in this.assembly.ExportedTypes 94 | where type.IsSubclassOf(typeof(Lexer)) && type.Name == name 95 | orderby type.Name 96 | select type).FirstOrDefault(); 97 | } 98 | 99 | private void LoadFromFile() 100 | { 101 | string content = this.GetFileContent(); 102 | this.txtText.Text = this.IsSqlParser() ? content.ToUpper() : content; 103 | this.LoadTree(); 104 | } 105 | 106 | private void btnOpenFile_Click(object sender, EventArgs e) 107 | { 108 | this.SelectFile(); 109 | } 110 | 111 | private void SelectFile() 112 | { 113 | if (this.cboParser.SelectedIndex < 0) 114 | { 115 | MessageBox.Show("Please select a parser first."); 116 | return; 117 | } 118 | 119 | ParserInfo info = this.GetParserInfo(); 120 | 121 | if (info == null) 122 | { 123 | return; 124 | } 125 | 126 | string extension = info.FileExtension; 127 | 128 | string filter = $"{info.Language} files|*{extension}|all files|*.*"; 129 | 130 | this.openFileDialog1.FileName = ""; 131 | this.openFileDialog1.Filter = filter; 132 | 133 | if (this.openFileDialog1.ShowDialog() == DialogResult.OK) 134 | { 135 | this.txtFile.Text = this.openFileDialog1.FileName; 136 | 137 | this.LoadFromFile(); 138 | } 139 | } 140 | 141 | private ParserInfo GetParserInfo() 142 | { 143 | string parserName = this.cboParser.Text; 144 | 145 | ParserInfo info = ParserManager.GetParserInfoByName(parserName); 146 | 147 | if (info == null) 148 | { 149 | MessageBox.Show($"Can't get ParserInfo for parser \"{parserName}\"."); 150 | return null; 151 | } 152 | 153 | return info; 154 | } 155 | 156 | private void txtFile_TextChanged(object sender, EventArgs e) 157 | { 158 | if (File.Exists(this.txtFile.Text)) 159 | { 160 | this.LoadFromFile(); 161 | } 162 | } 163 | 164 | private void ClearValues() 165 | { 166 | this.txtChildCount.Text = ""; 167 | this.txtTypeName.Text = ""; 168 | 169 | this.ClearSelection(); 170 | } 171 | 172 | private void ClearSelection() 173 | { 174 | int start = this.txtText.SelectionStart; 175 | 176 | this.txtText.SelectAll(); 177 | this.txtText.SelectionBackColor = Color.White; 178 | this.txtText.SelectionColor = Color.Black; 179 | this.txtText.SelectionStart = start; 180 | this.txtText.SelectionLength = 0; 181 | } 182 | 183 | private void LoadTree() 184 | { 185 | Task.Run(()=> this.InternalLoadTree()); 186 | } 187 | 188 | private void InternalLoadTree() 189 | { 190 | this.ClearValues(); 191 | this.txtMessage.Text = "is parsing..."; 192 | 193 | this.tvParserNodes.Nodes.Clear(); 194 | this.dictTokenInfo.Clear(); 195 | 196 | if (this.cboParser.SelectedIndex < 0) 197 | { 198 | return; 199 | } 200 | 201 | if (string.IsNullOrEmpty(this.txtText.Text)) 202 | { 203 | return; 204 | } 205 | 206 | string parserName = this.cboParser.Text; 207 | 208 | Type parserType = this.parserTypes.FirstOrDefault(item => item.Name == parserName); 209 | 210 | Type lexerType = this.GetLexerType(parserType.Name.Replace("Parser", "Lexer")); 211 | 212 | Lexer lexer = (Lexer)Activator.CreateInstance(lexerType, new object[] { CharStreams.fromString(this.txtText.Text) }); 213 | 214 | CommonTokenStream tokens = new CommonTokenStream(lexer); 215 | 216 | this.parser = (Parser)Activator.CreateInstance(parserType, new object[] { tokens }); 217 | 218 | var errorListener = new SqlSyntaxErrorListener(); 219 | 220 | this.parser.AddErrorListener(errorListener); 221 | 222 | ParserInfo info = this.GetParserInfo(); 223 | 224 | if (info == null) 225 | { 226 | return; 227 | } 228 | 229 | var rootMethod = parserType.GetMethod(info.EntryRuleName); 230 | 231 | object value = rootMethod.Invoke(this.parser, new object[] { }); 232 | 233 | this.error = errorListener.Error; 234 | 235 | if (this.chkHighlightingErrors.Checked) 236 | { 237 | this.HighlightingError(); 238 | } 239 | 240 | TreeNode rootNode = this.CreateTreeNode(info.EntryRuleName); 241 | rootNode.Tag = value; 242 | 243 | this.txtMessage.Text = "is loading tree..."; 244 | 245 | AddNodeDelegate @delegate = new AddNodeDelegate(this.AddTreeNode); 246 | this.Invoke(@delegate, rootNode); 247 | 248 | rootNode.Expand(); 249 | 250 | rootNode.EnsureVisible(); 251 | 252 | this.txtMessage.Text = ""; 253 | } 254 | 255 | private void AddTreeNode(TreeNode node) 256 | { 257 | this.tvParserNodes.Nodes.Add(node); 258 | 259 | this.AddChildNodes(node, false); 260 | } 261 | 262 | public void HighlightingError() 263 | { 264 | if (this.error != null) 265 | { 266 | bool enabled = this.chkHighlightingErrors.Checked; 267 | 268 | foreach (var item in this.error.Items) 269 | { 270 | this.txtText.SelectionStart = item.StartIndex; 271 | this.txtText.SelectionLength = item.StopIndex - item.StartIndex + 1; 272 | 273 | this.txtText.SelectionColor = enabled ? Color.Red : Color.Black; 274 | this.txtText.SelectionBackColor = enabled ? Color.Yellow : Color.White; 275 | } 276 | } 277 | 278 | this.txtText.SelectionStart = 0; 279 | this.txtText.SelectionLength = 0; 280 | this.txtText.Focus(); 281 | } 282 | 283 | private void AddChildNodes(TreeNode node, bool expand) 284 | { 285 | object value = node.Tag; 286 | 287 | if (value == null) 288 | { 289 | return; 290 | } 291 | 292 | List list = new List(); 293 | 294 | Type type = value.GetType(); 295 | 296 | if (type.IsArray) 297 | { 298 | object[] values = value as object[]; 299 | 300 | if (values != null) 301 | { 302 | list.AddRange(values); 303 | } 304 | else 305 | { 306 | list.Add(value); 307 | } 308 | } 309 | else 310 | { 311 | list.Add(value); 312 | } 313 | 314 | bool hideEmptyNode = this.chkHideEmptyNode.Checked; 315 | 316 | foreach (object v in list) 317 | { 318 | Type t = v.GetType(); 319 | 320 | if (this.rbMethods.Checked) 321 | { 322 | #region Methods 323 | 324 | MethodInfo[] methods = t.GetMethods(); 325 | 326 | foreach (MethodInfo m in methods) 327 | { 328 | if (m.IsPublic && !m.IsSpecialName && !ignoreMethods.Contains(m.Name) && m.Module.Name == this.coderPaserDllName && m.GetParameters().Length == 0) 329 | { 330 | var childValue = m.Invoke(v, new object[] { }); 331 | 332 | if (childValue == null && hideEmptyNode) 333 | { 334 | continue; 335 | } 336 | 337 | bool isArray = m.ReturnType.IsArray; 338 | int count = 0; 339 | 340 | if (isArray && childValue is IEnumerable treeNodes) 341 | { 342 | count = treeNodes.Count(); 343 | 344 | if (count == 0 && hideEmptyNode) 345 | { 346 | continue; 347 | } 348 | } 349 | 350 | string nodeText = isArray ? (m.Name + "[]") : m.Name; 351 | 352 | TreeNode childNode = this.CreateTreeNode(nodeText); 353 | childNode.Name = m.Name; 354 | 355 | childNode.Tag = childValue; 356 | 357 | node.Nodes.Add(childNode); 358 | 359 | this.dictTokenInfo.Add(childNode, this.GetTokenInfo(childValue)); 360 | 361 | this.AddChildNodes(childNode, false); 362 | } 363 | } 364 | 365 | #endregion 366 | } 367 | 368 | if (this.rbChildren.Checked) 369 | { 370 | #region Children 371 | 372 | var childrenField = type.GetField("children"); 373 | 374 | if (childrenField != null) 375 | { 376 | var children = childrenField.GetValue(value); 377 | 378 | if (children != null) 379 | { 380 | if (children is List treeNodes) 381 | { 382 | int i = 0; 383 | 384 | foreach (IParseTree tn in treeNodes) 385 | { 386 | if (tn is TerminalNodeImpl && tn.GetText() == "" && this.chkHideEmptyNode.Checked) 387 | { 388 | continue; 389 | } 390 | 391 | string childName = tn.GetType().Name; 392 | 393 | TreeNode childNode = this.CreateTreeNode($"{childName}"); 394 | childNode.Name = childName; 395 | childNode.Tag = tn; 396 | 397 | if (tn is ErrorNodeImpl) 398 | { 399 | childNode.ForeColor = Color.Red; 400 | } 401 | 402 | node.Nodes.Add(childNode); 403 | 404 | this.dictTokenInfo.Add(childNode, this.GetTokenInfo(tn)); 405 | 406 | this.AddChildNodes(childNode, false); 407 | 408 | i++; 409 | } 410 | } 411 | } 412 | } 413 | 414 | #endregion 415 | } 416 | } 417 | 418 | if (expand) 419 | { 420 | node.Expand(); 421 | } 422 | } 423 | 424 | private TreeNode CreateTreeNode(string text, string imageKey = null) 425 | { 426 | TreeNode node = new TreeNode(text); 427 | node.ImageKey = string.IsNullOrEmpty(imageKey) ? "" : imageKey; 428 | node.SelectedImageKey = node.ImageKey; 429 | 430 | return node; 431 | } 432 | 433 | private void txtFile_KeyUp(object sender, KeyEventArgs e) 434 | { 435 | if (e.KeyCode == Keys.Enter) 436 | { 437 | this.LoadFromFile(); 438 | } 439 | } 440 | 441 | private void tvParserNodes_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e) 442 | { 443 | if (e.Node.Nodes.Count > 0) 444 | { 445 | return; 446 | } 447 | 448 | this.AddChildNodes(e.Node, true); 449 | } 450 | 451 | private void tsmiExpandAll_Click(object sender, EventArgs e) 452 | { 453 | TreeNode node = this.tvParserNodes.SelectedNode; 454 | 455 | this.tvParserNodes.ExpandAll(); 456 | 457 | if (node != null) 458 | { 459 | node.EnsureVisible(); 460 | } 461 | } 462 | 463 | private void tsmiCollapseAll_Click(object sender, EventArgs e) 464 | { 465 | this.tvParserNodes.CollapseAll(); 466 | } 467 | 468 | private void tvParserNodes_AfterSelect(object sender, TreeViewEventArgs e) 469 | { 470 | this.ShowNodeDetails(e.Node); 471 | } 472 | 473 | private void ShowNodeDetails(TreeNode node) 474 | { 475 | if (this.tvParserNodes.SelectedNode != null && this.tvParserNodes.SelectedNode.Level == 0 && this.tvParserNodes.Nodes.Count == 1) 476 | { 477 | return; 478 | } 479 | 480 | this.ClearValues(); 481 | this.ClearSelection(); 482 | this.HighlightingError(); 483 | 484 | object value = node.Tag; 485 | 486 | if (value == null) 487 | { 488 | return; 489 | } 490 | 491 | Type type = value.GetType(); 492 | this.txtTypeName.Text = type.Name; 493 | 494 | TokenInfo tokenInfo = this.GetTokenInfo(value); 495 | 496 | this.txtChildCount.Text = tokenInfo.ChildCount?.ToString(); 497 | 498 | if (!tokenInfo.StartIndex.HasValue || tokenInfo.StartIndex < 0 || !tokenInfo.StopIndex.HasValue || tokenInfo.StopIndex < 0) 499 | { 500 | return; 501 | } 502 | 503 | int length = tokenInfo.StopIndex.Value - tokenInfo.StartIndex.Value + 1; 504 | 505 | if (length > 0) 506 | { 507 | this.txtText.SelectionStart = tokenInfo.StartIndex.Value; 508 | this.txtText.SelectionLength = length; 509 | this.txtText.SelectionBackColor = this.selectionBackColor; 510 | this.txtText.SelectionColor = Color.White; 511 | 512 | this.txtText.ScrollToCaret(); 513 | } 514 | 515 | this.txtMessage.Text = this.GetTreeNodePath(node); 516 | } 517 | 518 | private TokenInfo GetTokenInfo(dynamic value) 519 | { 520 | TokenInfo tokenInfo = new TokenInfo(); 521 | 522 | if (value is ParserRuleContext context) 523 | { 524 | tokenInfo.StartIndex = context.Start?.StartIndex; 525 | tokenInfo.StopIndex = context.Stop?.StopIndex; 526 | tokenInfo.ChildCount = context.children?.Count; 527 | } 528 | else if (value is ParserRuleContext[] contextes) 529 | { 530 | if (contextes.Any()) 531 | { 532 | tokenInfo.StartIndex = contextes.First().Start?.StartIndex; 533 | tokenInfo.StopIndex = contextes.Last().Stop?.StopIndex; 534 | tokenInfo.ChildCount = contextes.Length; 535 | } 536 | } 537 | else if (value is ITerminalNode terminalNode) 538 | { 539 | tokenInfo.StartIndex = terminalNode.Symbol?.StartIndex; 540 | tokenInfo.StopIndex = terminalNode.Symbol?.StopIndex; 541 | tokenInfo.ChildCount = terminalNode.ChildCount; 542 | } 543 | else if (value is ITerminalNode[] terminalNodes) 544 | { 545 | if (terminalNodes.Any()) 546 | { 547 | tokenInfo.StartIndex = terminalNodes.First().Symbol?.StartIndex; 548 | tokenInfo.StopIndex = terminalNodes.Last().Symbol?.StopIndex; 549 | tokenInfo.ChildCount = terminalNodes.Length; 550 | } 551 | } 552 | 553 | return tokenInfo; 554 | } 555 | 556 | private string GetFileContent() 557 | { 558 | string filePath = this.txtFile.Text; 559 | 560 | if (File.Exists(filePath)) 561 | { 562 | return File.ReadAllText(filePath); 563 | } 564 | 565 | return string.Empty; 566 | } 567 | 568 | private void frmMain_DragDrop(object sender, DragEventArgs e) 569 | { 570 | this.SetDropFiles(e); 571 | } 572 | 573 | private void frmMain_DragOver(object sender, DragEventArgs e) 574 | { 575 | this.SetDragEffect(e); 576 | } 577 | 578 | private void SetDragEffect(DragEventArgs e) 579 | { 580 | if (e.Data.GetDataPresent(DataFormats.FileDrop)) 581 | { 582 | e.Effect = DragDropEffects.Copy; 583 | } 584 | else 585 | { 586 | e.Effect = DragDropEffects.None; 587 | } 588 | } 589 | 590 | private void SetDropFiles(DragEventArgs e) 591 | { 592 | if (e.Data.GetDataPresent(DataFormats.FileDrop)) 593 | { 594 | string[] filePaths = (string[])e.Data.GetData(DataFormats.FileDrop.ToString()); 595 | 596 | string filePath = filePaths.FirstOrDefault(); 597 | 598 | if (!string.IsNullOrEmpty(filePath) && filePath != this.txtFile.Text) 599 | { 600 | this.txtFile.Text = filePath; 601 | 602 | this.LoadFromFile(); 603 | } 604 | } 605 | } 606 | 607 | private void rbChildren_CheckedChanged(object sender, EventArgs e) 608 | { 609 | this.LoadTree(); 610 | } 611 | 612 | private void rbMethods_CheckedChanged(object sender, EventArgs e) 613 | { 614 | this.LoadTree(); 615 | } 616 | 617 | private void btnReload_Click(object sender, EventArgs e) 618 | { 619 | if (File.Exists(this.txtFile.Text)) 620 | { 621 | this.LoadFromFile(); 622 | } 623 | else 624 | { 625 | this.LoadTree(); 626 | } 627 | } 628 | 629 | private void tvParserNodes_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) 630 | { 631 | if (e.Button == MouseButtons.Right) 632 | { 633 | this.tvParserNodes.SelectedNode = e.Node; 634 | 635 | this.SetMenuItemVisible(e.Node); 636 | 637 | this.treeContextMenu.Show(Cursor.Position); 638 | } 639 | } 640 | 641 | private void SetMenuItemVisible(TreeNode node) 642 | { 643 | this.tsmiCollapseToChildren.Visible = node != null; 644 | this.tsmiCopyPath.Visible = node != null; 645 | } 646 | 647 | private void tvParserNodes_MouseClick(object sender, MouseEventArgs e) 648 | { 649 | if (e.Button == MouseButtons.Right && this.tvParserNodes.SelectedNode == null) 650 | { 651 | this.SetMenuItemVisible(null); 652 | 653 | this.treeContextMenu.Show(Cursor.Position); 654 | } 655 | } 656 | 657 | private void tsmiCollapseToChildren_Click(object sender, EventArgs e) 658 | { 659 | TreeNode node = this.tvParserNodes.SelectedNode; 660 | 661 | if (node != null) 662 | { 663 | node.Collapse(false); 664 | } 665 | } 666 | 667 | private string GetTreeNodePath(TreeNode node) 668 | { 669 | List texts = new List(); 670 | 671 | texts.Add(string.IsNullOrEmpty(node.Name) ? node.Text : node.Name); 672 | 673 | TreeNode parent = node.Parent; 674 | while (parent != null) 675 | { 676 | texts.Add(string.IsNullOrEmpty(parent.Name) ? parent.Text : parent.Name); 677 | parent = parent.Parent; 678 | } 679 | 680 | texts.Reverse(); 681 | 682 | return string.Join(" > ", texts); 683 | } 684 | 685 | private void tsmiCopyPath_Click(object sender, EventArgs e) 686 | { 687 | this.CopyNodeText(true); 688 | } 689 | 690 | private void tsmiCopyText_Click(object sender, EventArgs e) 691 | { 692 | this.CopyNodeText(false); 693 | } 694 | 695 | private void CopyNodeText(bool isCopyPath) 696 | { 697 | TreeNode node = this.tvParserNodes.SelectedNode; 698 | 699 | if (node != null) 700 | { 701 | if (isCopyPath) 702 | { 703 | string path = this.GetTreeNodePath(node); 704 | 705 | if (!string.IsNullOrEmpty(path)) 706 | { 707 | Clipboard.SetDataObject(path); 708 | } 709 | } 710 | else 711 | { 712 | Clipboard.SetDataObject(node.Text); 713 | } 714 | 715 | MessageBox.Show("Has been copied to clipboard."); 716 | 717 | this.tvParserNodes.SelectedNode = node; 718 | } 719 | } 720 | 721 | private void tsmiExpandAllChildren_Click(object sender, EventArgs e) 722 | { 723 | TreeNode node = this.tvParserNodes.SelectedNode; 724 | 725 | if (node != null) 726 | { 727 | node.ExpandAll(); 728 | node.EnsureVisible(); 729 | } 730 | } 731 | 732 | private void txtMessage_MouseDoubleClick(object sender, MouseEventArgs e) 733 | { 734 | this.txtMessage.SelectAll(); 735 | } 736 | 737 | private void txtFile_MouseDoubleClick(object sender, MouseEventArgs e) 738 | { 739 | this.SelectFile(); 740 | } 741 | 742 | private void tsmiPaste_Click(object sender, EventArgs e) 743 | { 744 | var data = Clipboard.GetDataObject(); 745 | if (data != null) 746 | { 747 | this.txtText.Text = data.GetData(DataFormats.UnicodeText)?.ToString(); 748 | 749 | this.LoadTree(); 750 | } 751 | } 752 | 753 | private void cboParser_SelectedIndexChanged(object sender, EventArgs e) 754 | { 755 | this.LoadTree(); 756 | } 757 | 758 | private void tsmiClearSelection_Click(object sender, EventArgs e) 759 | { 760 | this.ClearSelection(); 761 | this.HighlightingError(); 762 | } 763 | 764 | private void tsmiNavigateToTreeNode_Click(object sender, EventArgs e) 765 | { 766 | if (this.txtText.SelectionLength > 0) 767 | { 768 | int start = this.txtText.SelectionStart + (this.txtText.SelectedText.Length - this.txtText.SelectedText.TrimStart().Length); 769 | int length = this.txtText.SelectedText.Trim().Replace("\n", "").Length; 770 | 771 | TreeNode node = this.FindTreeNode(start, length); 772 | 773 | if (node != null) 774 | { 775 | this.tvParserNodes.SelectedNode = node; 776 | 777 | node.EnsureVisible(); 778 | } 779 | else 780 | { 781 | MessageBox.Show("No match."); 782 | } 783 | } 784 | } 785 | 786 | private TreeNode FindTreeNode(int start, int lenght) 787 | { 788 | int end = start + lenght - 1; 789 | 790 | TreeNode node = this.dictTokenInfo 791 | .Where(item => item.Value.StartIndex.HasValue && item.Value.StopIndex.HasValue && start >= item.Value.StartIndex && end <= item.Value.StopIndex) 792 | .OrderByDescending(item => item.Key.Level) 793 | .Select(item => item.Key) 794 | .FirstOrDefault(); 795 | 796 | return node; 797 | } 798 | 799 | private void btnReset_Click(object sender, EventArgs e) 800 | { 801 | this.Reset(); 802 | } 803 | 804 | private void Reset() 805 | { 806 | this.cboParser.SelectedIndex = -1; 807 | this.txtFile.Text = ""; 808 | this.ClearValues(); 809 | this.tvParserNodes.Nodes.Clear(); 810 | this.txtText.Text = ""; 811 | this.txtMessage.Text = ""; 812 | } 813 | 814 | private void txtText_MouseUp(object sender, MouseEventArgs e) 815 | { 816 | if (e.Button == MouseButtons.Right) 817 | { 818 | this.tsmiNavigateToTreeNode.Visible = this.txtText.SelectionLength > 0; 819 | this.tsmiPaste.Visible = this.txtText.Text.Length == 0 || this.txtText.SelectionLength == this.txtText.Text.Length; 820 | 821 | this.textContextMenu.Show(this.txtText, e.Location); 822 | } 823 | } 824 | 825 | private void txtMessage_MouseEnter(object sender, EventArgs e) 826 | { 827 | this.toolTip1.SetToolTip(this.txtMessage, this.txtMessage.Text); 828 | } 829 | 830 | private void txtText_KeyDown(object sender, KeyEventArgs e) 831 | { 832 | if (e.Control) 833 | { 834 | if (e.KeyCode == Keys.V) 835 | { 836 | this.txtFile.Text = ""; 837 | 838 | if (this.IsSqlParser() && (this.txtText.Text.Length == 0 || this.txtText.SelectedText.Length == this.txtText.Text.Length)) 839 | { 840 | e.SuppressKeyPress = true; 841 | 842 | this.txtText.Clear(); 843 | 844 | string content = Clipboard.GetText(); 845 | 846 | this.txtText.AppendText(content); 847 | } 848 | 849 | this.LoadTree(); 850 | } 851 | else if (e.KeyCode.HasFlag(Keys.U)) 852 | { 853 | if (e.Shift) 854 | { 855 | this.txtText.SelectedText = this.txtText.SelectedText.ToUpper(); 856 | 857 | if (this.txtText.SelectionLength == this.txtText.TextLength) 858 | { 859 | this.LoadTree(); 860 | } 861 | } 862 | else 863 | { 864 | this.txtText.SelectedText = this.txtText.SelectedText.ToLower(); 865 | } 866 | } 867 | } 868 | } 869 | 870 | private void tsmiConvertToUpperCase_Click(object sender, EventArgs e) 871 | { 872 | this.txtText.Text = this.txtText.Text.ToUpper(); 873 | } 874 | 875 | private void tsmiConvertToLowerCase_Click(object sender, EventArgs e) 876 | { 877 | this.txtText.Text = this.txtText.Text.ToLower(); 878 | } 879 | 880 | private void txtText_SelectionChanged(object sender, EventArgs e) 881 | { 882 | this.txtText.SelectionFont = this.txtText.Font; 883 | } 884 | 885 | private void tsmiParseCurrent_Click(object sender, EventArgs e) 886 | { 887 | 888 | } 889 | 890 | private void tsmiClearContent_Click(object sender, EventArgs e) 891 | { 892 | this.txtText.Clear(); 893 | } 894 | 895 | private void chkHighlightingErrors_CheckedChanged(object sender, EventArgs e) 896 | { 897 | this.HighlightingError(); 898 | } 899 | } 900 | } 901 | -------------------------------------------------------------------------------- /CodeParser.Viewer/frmMain.designer.cs: -------------------------------------------------------------------------------- 1 | namespace CodeParser.Viewer 2 | { 3 | partial class frmMain 4 | { 5 | /// 6 | /// 必需的设计器变量。 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// 清理所有正在使用的资源。 12 | /// 13 | /// 如果应释放托管资源,为 true;否则为 false。 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows 窗体设计器生成的代码 24 | 25 | /// 26 | /// 设计器支持所需的方法 - 不要修改 27 | /// 使用代码编辑器修改此方法的内容。 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.components = new System.ComponentModel.Container(); 32 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(frmMain)); 33 | this.splitContainer1 = new System.Windows.Forms.SplitContainer(); 34 | this.tvParserNodes = new System.Windows.Forms.TreeView(); 35 | this.txtText = new System.Windows.Forms.RichTextBox(); 36 | this.txtChildCount = new System.Windows.Forms.TextBox(); 37 | this.txtTypeName = new System.Windows.Forms.TextBox(); 38 | this.label3 = new System.Windows.Forms.Label(); 39 | this.label4 = new System.Windows.Forms.Label(); 40 | this.textContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components); 41 | this.tsmiPaste = new System.Windows.Forms.ToolStripMenuItem(); 42 | this.tsmiNavigateToTreeNode = new System.Windows.Forms.ToolStripMenuItem(); 43 | this.tsmiClearSelection = new System.Windows.Forms.ToolStripMenuItem(); 44 | this.tsmiClearContent = new System.Windows.Forms.ToolStripMenuItem(); 45 | this.treeContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components); 46 | this.tsmiExpandAll = new System.Windows.Forms.ToolStripMenuItem(); 47 | this.tsmiCollapseAll = new System.Windows.Forms.ToolStripMenuItem(); 48 | this.tsmiExpandAllChildren = new System.Windows.Forms.ToolStripMenuItem(); 49 | this.tsmiCollapseToChildren = new System.Windows.Forms.ToolStripMenuItem(); 50 | this.tsmiCopyText = new System.Windows.Forms.ToolStripMenuItem(); 51 | this.tsmiCopyPath = new System.Windows.Forms.ToolStripMenuItem(); 52 | this.label1 = new System.Windows.Forms.Label(); 53 | this.cboParser = new System.Windows.Forms.ComboBox(); 54 | this.txtFile = new System.Windows.Forms.TextBox(); 55 | this.btnOpenFile = new System.Windows.Forms.Button(); 56 | this.label2 = new System.Windows.Forms.Label(); 57 | this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); 58 | this.chkHideEmptyNode = new System.Windows.Forms.CheckBox(); 59 | this.label5 = new System.Windows.Forms.Label(); 60 | this.rbChildren = new System.Windows.Forms.RadioButton(); 61 | this.rbMethods = new System.Windows.Forms.RadioButton(); 62 | this.btnReload = new System.Windows.Forms.Button(); 63 | this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); 64 | this.txtMessage = new System.Windows.Forms.TextBox(); 65 | this.btnReset = new System.Windows.Forms.Button(); 66 | this.chkHighlightingErrors = new System.Windows.Forms.CheckBox(); 67 | ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); 68 | this.splitContainer1.Panel1.SuspendLayout(); 69 | this.splitContainer1.Panel2.SuspendLayout(); 70 | this.splitContainer1.SuspendLayout(); 71 | this.textContextMenu.SuspendLayout(); 72 | this.treeContextMenu.SuspendLayout(); 73 | this.SuspendLayout(); 74 | // 75 | // splitContainer1 76 | // 77 | this.splitContainer1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 78 | | System.Windows.Forms.AnchorStyles.Left) 79 | | System.Windows.Forms.AnchorStyles.Right))); 80 | this.splitContainer1.Location = new System.Drawing.Point(3, 62); 81 | this.splitContainer1.Name = "splitContainer1"; 82 | // 83 | // splitContainer1.Panel1 84 | // 85 | this.splitContainer1.Panel1.Controls.Add(this.tvParserNodes); 86 | // 87 | // splitContainer1.Panel2 88 | // 89 | this.splitContainer1.Panel2.Controls.Add(this.txtText); 90 | this.splitContainer1.Panel2.Controls.Add(this.txtChildCount); 91 | this.splitContainer1.Panel2.Controls.Add(this.txtTypeName); 92 | this.splitContainer1.Panel2.Controls.Add(this.label3); 93 | this.splitContainer1.Panel2.Controls.Add(this.label4); 94 | this.splitContainer1.Size = new System.Drawing.Size(832, 461); 95 | this.splitContainer1.SplitterDistance = 418; 96 | this.splitContainer1.TabIndex = 0; 97 | // 98 | // tvParserNodes 99 | // 100 | this.tvParserNodes.Dock = System.Windows.Forms.DockStyle.Fill; 101 | this.tvParserNodes.HideSelection = false; 102 | this.tvParserNodes.Location = new System.Drawing.Point(0, 0); 103 | this.tvParserNodes.Name = "tvParserNodes"; 104 | this.tvParserNodes.Size = new System.Drawing.Size(418, 461); 105 | this.tvParserNodes.TabIndex = 0; 106 | this.tvParserNodes.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.tvParserNodes_AfterSelect); 107 | this.tvParserNodes.NodeMouseClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.tvParserNodes_NodeMouseClick); 108 | this.tvParserNodes.NodeMouseDoubleClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.tvParserNodes_NodeMouseDoubleClick); 109 | this.tvParserNodes.MouseClick += new System.Windows.Forms.MouseEventHandler(this.tvParserNodes_MouseClick); 110 | // 111 | // txtText 112 | // 113 | this.txtText.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 114 | | System.Windows.Forms.AnchorStyles.Left) 115 | | System.Windows.Forms.AnchorStyles.Right))); 116 | this.txtText.BackColor = System.Drawing.Color.White; 117 | this.txtText.Font = new System.Drawing.Font("Calibri", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 118 | this.txtText.Location = new System.Drawing.Point(3, 82); 119 | this.txtText.Name = "txtText"; 120 | this.txtText.Size = new System.Drawing.Size(404, 379); 121 | this.txtText.TabIndex = 7; 122 | this.txtText.Text = ""; 123 | this.txtText.SelectionChanged += new System.EventHandler(this.txtText_SelectionChanged); 124 | this.txtText.KeyDown += new System.Windows.Forms.KeyEventHandler(this.txtText_KeyDown); 125 | this.txtText.MouseUp += new System.Windows.Forms.MouseEventHandler(this.txtText_MouseUp); 126 | // 127 | // txtChildCount 128 | // 129 | this.txtChildCount.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 130 | | System.Windows.Forms.AnchorStyles.Right))); 131 | this.txtChildCount.BackColor = System.Drawing.Color.White; 132 | this.txtChildCount.Location = new System.Drawing.Point(86, 37); 133 | this.txtChildCount.Name = "txtChildCount"; 134 | this.txtChildCount.ReadOnly = true; 135 | this.txtChildCount.Size = new System.Drawing.Size(319, 21); 136 | this.txtChildCount.TabIndex = 6; 137 | // 138 | // txtTypeName 139 | // 140 | this.txtTypeName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 141 | | System.Windows.Forms.AnchorStyles.Right))); 142 | this.txtTypeName.BackColor = System.Drawing.Color.White; 143 | this.txtTypeName.Location = new System.Drawing.Point(86, 10); 144 | this.txtTypeName.Name = "txtTypeName"; 145 | this.txtTypeName.ReadOnly = true; 146 | this.txtTypeName.Size = new System.Drawing.Size(319, 21); 147 | this.txtTypeName.TabIndex = 5; 148 | // 149 | // label3 150 | // 151 | this.label3.AutoSize = true; 152 | this.label3.Location = new System.Drawing.Point(6, 13); 153 | this.label3.Name = "label3"; 154 | this.label3.Size = new System.Drawing.Size(65, 12); 155 | this.label3.TabIndex = 4; 156 | this.label3.Text = "Type name:"; 157 | // 158 | // label4 159 | // 160 | this.label4.AutoSize = true; 161 | this.label4.Location = new System.Drawing.Point(6, 41); 162 | this.label4.Name = "label4"; 163 | this.label4.Size = new System.Drawing.Size(77, 12); 164 | this.label4.TabIndex = 2; 165 | this.label4.Text = "Child count:"; 166 | // 167 | // textContextMenu 168 | // 169 | this.textContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 170 | this.tsmiPaste, 171 | this.tsmiNavigateToTreeNode, 172 | this.tsmiClearSelection, 173 | this.tsmiClearContent}); 174 | this.textContextMenu.Name = "textContextMenu"; 175 | this.textContextMenu.Size = new System.Drawing.Size(206, 92); 176 | // 177 | // tsmiPaste 178 | // 179 | this.tsmiPaste.Name = "tsmiPaste"; 180 | this.tsmiPaste.Size = new System.Drawing.Size(205, 22); 181 | this.tsmiPaste.Text = "Paste"; 182 | this.tsmiPaste.Click += new System.EventHandler(this.tsmiPaste_Click); 183 | // 184 | // tsmiNavigateToTreeNode 185 | // 186 | this.tsmiNavigateToTreeNode.Name = "tsmiNavigateToTreeNode"; 187 | this.tsmiNavigateToTreeNode.Size = new System.Drawing.Size(205, 22); 188 | this.tsmiNavigateToTreeNode.Text = "Navigate to tree node"; 189 | this.tsmiNavigateToTreeNode.Click += new System.EventHandler(this.tsmiNavigateToTreeNode_Click); 190 | // 191 | // tsmiClearSelection 192 | // 193 | this.tsmiClearSelection.Name = "tsmiClearSelection"; 194 | this.tsmiClearSelection.Size = new System.Drawing.Size(205, 22); 195 | this.tsmiClearSelection.Text = "Clear Selection"; 196 | this.tsmiClearSelection.Click += new System.EventHandler(this.tsmiClearSelection_Click); 197 | // 198 | // tsmiClearContent 199 | // 200 | this.tsmiClearContent.Name = "tsmiClearContent"; 201 | this.tsmiClearContent.Size = new System.Drawing.Size(205, 22); 202 | this.tsmiClearContent.Text = "Clear Content"; 203 | this.tsmiClearContent.Click += new System.EventHandler(this.tsmiClearContent_Click); 204 | // 205 | // treeContextMenu 206 | // 207 | this.treeContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 208 | this.tsmiExpandAll, 209 | this.tsmiCollapseAll, 210 | this.tsmiExpandAllChildren, 211 | this.tsmiCollapseToChildren, 212 | this.tsmiCopyText, 213 | this.tsmiCopyPath}); 214 | this.treeContextMenu.Name = "contextMenuStrip1"; 215 | this.treeContextMenu.Size = new System.Drawing.Size(192, 136); 216 | // 217 | // tsmiExpandAll 218 | // 219 | this.tsmiExpandAll.Name = "tsmiExpandAll"; 220 | this.tsmiExpandAll.Size = new System.Drawing.Size(191, 22); 221 | this.tsmiExpandAll.Text = "expand all"; 222 | this.tsmiExpandAll.Click += new System.EventHandler(this.tsmiExpandAll_Click); 223 | // 224 | // tsmiCollapseAll 225 | // 226 | this.tsmiCollapseAll.Name = "tsmiCollapseAll"; 227 | this.tsmiCollapseAll.Size = new System.Drawing.Size(191, 22); 228 | this.tsmiCollapseAll.Text = "collapse all"; 229 | this.tsmiCollapseAll.Click += new System.EventHandler(this.tsmiCollapseAll_Click); 230 | // 231 | // tsmiExpandAllChildren 232 | // 233 | this.tsmiExpandAllChildren.Name = "tsmiExpandAllChildren"; 234 | this.tsmiExpandAllChildren.Size = new System.Drawing.Size(191, 22); 235 | this.tsmiExpandAllChildren.Text = "expand all children"; 236 | this.tsmiExpandAllChildren.Click += new System.EventHandler(this.tsmiExpandAllChildren_Click); 237 | // 238 | // tsmiCollapseToChildren 239 | // 240 | this.tsmiCollapseToChildren.Name = "tsmiCollapseToChildren"; 241 | this.tsmiCollapseToChildren.Size = new System.Drawing.Size(191, 22); 242 | this.tsmiCollapseToChildren.Text = "collapse all children"; 243 | this.tsmiCollapseToChildren.Click += new System.EventHandler(this.tsmiCollapseToChildren_Click); 244 | // 245 | // tsmiCopyText 246 | // 247 | this.tsmiCopyText.Name = "tsmiCopyText"; 248 | this.tsmiCopyText.Size = new System.Drawing.Size(191, 22); 249 | this.tsmiCopyText.Text = "copy text"; 250 | this.tsmiCopyText.Click += new System.EventHandler(this.tsmiCopyText_Click); 251 | // 252 | // tsmiCopyPath 253 | // 254 | this.tsmiCopyPath.Name = "tsmiCopyPath"; 255 | this.tsmiCopyPath.Size = new System.Drawing.Size(191, 22); 256 | this.tsmiCopyPath.Text = "copy path"; 257 | this.tsmiCopyPath.Click += new System.EventHandler(this.tsmiCopyPath_Click); 258 | // 259 | // label1 260 | // 261 | this.label1.AutoSize = true; 262 | this.label1.Location = new System.Drawing.Point(4, 12); 263 | this.label1.Name = "label1"; 264 | this.label1.Size = new System.Drawing.Size(47, 12); 265 | this.label1.TabIndex = 1; 266 | this.label1.Text = "Parser:"; 267 | // 268 | // cboParser 269 | // 270 | this.cboParser.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 271 | this.cboParser.FormattingEnabled = true; 272 | this.cboParser.Location = new System.Drawing.Point(57, 9); 273 | this.cboParser.Name = "cboParser"; 274 | this.cboParser.Size = new System.Drawing.Size(115, 20); 275 | this.cboParser.TabIndex = 2; 276 | this.cboParser.SelectedIndexChanged += new System.EventHandler(this.cboParser_SelectedIndexChanged); 277 | // 278 | // txtFile 279 | // 280 | this.txtFile.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 281 | | System.Windows.Forms.AnchorStyles.Right))); 282 | this.txtFile.Location = new System.Drawing.Point(57, 35); 283 | this.txtFile.Name = "txtFile"; 284 | this.txtFile.Size = new System.Drawing.Size(625, 21); 285 | this.txtFile.TabIndex = 3; 286 | this.txtFile.TextChanged += new System.EventHandler(this.txtFile_TextChanged); 287 | this.txtFile.KeyUp += new System.Windows.Forms.KeyEventHandler(this.txtFile_KeyUp); 288 | this.txtFile.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.txtFile_MouseDoubleClick); 289 | // 290 | // btnOpenFile 291 | // 292 | this.btnOpenFile.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 293 | this.btnOpenFile.Location = new System.Drawing.Point(682, 34); 294 | this.btnOpenFile.Name = "btnOpenFile"; 295 | this.btnOpenFile.Size = new System.Drawing.Size(36, 23); 296 | this.btnOpenFile.TabIndex = 4; 297 | this.btnOpenFile.Text = "..."; 298 | this.btnOpenFile.UseVisualStyleBackColor = true; 299 | this.btnOpenFile.Click += new System.EventHandler(this.btnOpenFile_Click); 300 | // 301 | // label2 302 | // 303 | this.label2.AutoSize = true; 304 | this.label2.Location = new System.Drawing.Point(5, 39); 305 | this.label2.Name = "label2"; 306 | this.label2.Size = new System.Drawing.Size(35, 12); 307 | this.label2.TabIndex = 5; 308 | this.label2.Text = "File:"; 309 | // 310 | // chkHideEmptyNode 311 | // 312 | this.chkHideEmptyNode.AutoSize = true; 313 | this.chkHideEmptyNode.Checked = true; 314 | this.chkHideEmptyNode.CheckState = System.Windows.Forms.CheckState.Checked; 315 | this.chkHideEmptyNode.Location = new System.Drawing.Point(445, 12); 316 | this.chkHideEmptyNode.Name = "chkHideEmptyNode"; 317 | this.chkHideEmptyNode.Size = new System.Drawing.Size(114, 16); 318 | this.chkHideEmptyNode.TabIndex = 7; 319 | this.chkHideEmptyNode.Text = "Hide empty node"; 320 | this.chkHideEmptyNode.UseVisualStyleBackColor = true; 321 | // 322 | // label5 323 | // 324 | this.label5.AutoSize = true; 325 | this.label5.Location = new System.Drawing.Point(209, 13); 326 | this.label5.Name = "label5"; 327 | this.label5.Size = new System.Drawing.Size(65, 12); 328 | this.label5.TabIndex = 8; 329 | this.label5.Text = "Load mode:"; 330 | // 331 | // rbChildren 332 | // 333 | this.rbChildren.AutoSize = true; 334 | this.rbChildren.Checked = true; 335 | this.rbChildren.Location = new System.Drawing.Point(280, 12); 336 | this.rbChildren.Name = "rbChildren"; 337 | this.rbChildren.Size = new System.Drawing.Size(71, 16); 338 | this.rbChildren.TabIndex = 9; 339 | this.rbChildren.TabStop = true; 340 | this.rbChildren.Text = "children"; 341 | this.rbChildren.UseVisualStyleBackColor = true; 342 | this.rbChildren.CheckedChanged += new System.EventHandler(this.rbChildren_CheckedChanged); 343 | // 344 | // rbMethods 345 | // 346 | this.rbMethods.AutoSize = true; 347 | this.rbMethods.Location = new System.Drawing.Point(357, 12); 348 | this.rbMethods.Name = "rbMethods"; 349 | this.rbMethods.Size = new System.Drawing.Size(65, 16); 350 | this.rbMethods.TabIndex = 10; 351 | this.rbMethods.Text = "methods"; 352 | this.rbMethods.UseVisualStyleBackColor = true; 353 | this.rbMethods.CheckedChanged += new System.EventHandler(this.rbMethods_CheckedChanged); 354 | // 355 | // btnReload 356 | // 357 | this.btnReload.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 358 | this.btnReload.Location = new System.Drawing.Point(723, 34); 359 | this.btnReload.Name = "btnReload"; 360 | this.btnReload.Size = new System.Drawing.Size(53, 23); 361 | this.btnReload.TabIndex = 11; 362 | this.btnReload.Text = "Reload"; 363 | this.btnReload.UseVisualStyleBackColor = true; 364 | this.btnReload.Click += new System.EventHandler(this.btnReload_Click); 365 | // 366 | // txtMessage 367 | // 368 | this.txtMessage.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 369 | | System.Windows.Forms.AnchorStyles.Right))); 370 | this.txtMessage.BorderStyle = System.Windows.Forms.BorderStyle.None; 371 | this.txtMessage.Location = new System.Drawing.Point(0, 529); 372 | this.txtMessage.Name = "txtMessage"; 373 | this.txtMessage.ReadOnly = true; 374 | this.txtMessage.Size = new System.Drawing.Size(837, 14); 375 | this.txtMessage.TabIndex = 12; 376 | this.txtMessage.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.txtMessage_MouseDoubleClick); 377 | this.txtMessage.MouseEnter += new System.EventHandler(this.txtMessage_MouseEnter); 378 | // 379 | // btnReset 380 | // 381 | this.btnReset.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 382 | this.btnReset.Location = new System.Drawing.Point(780, 34); 383 | this.btnReset.Name = "btnReset"; 384 | this.btnReset.Size = new System.Drawing.Size(51, 23); 385 | this.btnReset.TabIndex = 13; 386 | this.btnReset.Text = "Reset"; 387 | this.btnReset.UseVisualStyleBackColor = true; 388 | this.btnReset.Click += new System.EventHandler(this.btnReset_Click); 389 | // 390 | // chkHighlightingErrors 391 | // 392 | this.chkHighlightingErrors.AutoSize = true; 393 | this.chkHighlightingErrors.Checked = true; 394 | this.chkHighlightingErrors.CheckState = System.Windows.Forms.CheckState.Checked; 395 | this.chkHighlightingErrors.Location = new System.Drawing.Point(577, 13); 396 | this.chkHighlightingErrors.Name = "chkHighlightingErrors"; 397 | this.chkHighlightingErrors.Size = new System.Drawing.Size(138, 16); 398 | this.chkHighlightingErrors.TabIndex = 14; 399 | this.chkHighlightingErrors.Text = "Highlighting errors"; 400 | this.chkHighlightingErrors.UseVisualStyleBackColor = true; 401 | this.chkHighlightingErrors.CheckedChanged += new System.EventHandler(this.chkHighlightingErrors_CheckedChanged); 402 | // 403 | // frmMain 404 | // 405 | this.AllowDrop = true; 406 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 407 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 408 | this.ClientSize = new System.Drawing.Size(837, 548); 409 | this.Controls.Add(this.chkHighlightingErrors); 410 | this.Controls.Add(this.btnReset); 411 | this.Controls.Add(this.txtMessage); 412 | this.Controls.Add(this.btnReload); 413 | this.Controls.Add(this.rbMethods); 414 | this.Controls.Add(this.rbChildren); 415 | this.Controls.Add(this.label5); 416 | this.Controls.Add(this.chkHideEmptyNode); 417 | this.Controls.Add(this.label2); 418 | this.Controls.Add(this.btnOpenFile); 419 | this.Controls.Add(this.txtFile); 420 | this.Controls.Add(this.cboParser); 421 | this.Controls.Add(this.label1); 422 | this.Controls.Add(this.splitContainer1); 423 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 424 | this.Name = "frmMain"; 425 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; 426 | this.Text = "CodeParser viewer"; 427 | this.Load += new System.EventHandler(this.frmMain_Load); 428 | this.DragDrop += new System.Windows.Forms.DragEventHandler(this.frmMain_DragDrop); 429 | this.DragOver += new System.Windows.Forms.DragEventHandler(this.frmMain_DragOver); 430 | this.splitContainer1.Panel1.ResumeLayout(false); 431 | this.splitContainer1.Panel2.ResumeLayout(false); 432 | this.splitContainer1.Panel2.PerformLayout(); 433 | ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); 434 | this.splitContainer1.ResumeLayout(false); 435 | this.textContextMenu.ResumeLayout(false); 436 | this.treeContextMenu.ResumeLayout(false); 437 | this.ResumeLayout(false); 438 | this.PerformLayout(); 439 | 440 | } 441 | 442 | #endregion 443 | 444 | private System.Windows.Forms.SplitContainer splitContainer1; 445 | private System.Windows.Forms.TreeView tvParserNodes; 446 | private System.Windows.Forms.Label label1; 447 | private System.Windows.Forms.ComboBox cboParser; 448 | private System.Windows.Forms.TextBox txtFile; 449 | private System.Windows.Forms.Button btnOpenFile; 450 | private System.Windows.Forms.Label label2; 451 | private System.Windows.Forms.TextBox txtChildCount; 452 | private System.Windows.Forms.TextBox txtTypeName; 453 | private System.Windows.Forms.Label label3; 454 | private System.Windows.Forms.Label label4; 455 | private System.Windows.Forms.OpenFileDialog openFileDialog1; 456 | private System.Windows.Forms.ContextMenuStrip treeContextMenu; 457 | private System.Windows.Forms.ToolStripMenuItem tsmiExpandAll; 458 | private System.Windows.Forms.ToolStripMenuItem tsmiCollapseAll; 459 | private System.Windows.Forms.CheckBox chkHideEmptyNode; 460 | private System.Windows.Forms.Label label5; 461 | private System.Windows.Forms.RadioButton rbChildren; 462 | private System.Windows.Forms.RadioButton rbMethods; 463 | private System.Windows.Forms.Button btnReload; 464 | private System.Windows.Forms.ToolStripMenuItem tsmiCollapseToChildren; 465 | private System.Windows.Forms.ToolStripMenuItem tsmiCopyPath; 466 | private System.Windows.Forms.ToolTip toolTip1; 467 | private System.Windows.Forms.RichTextBox txtText; 468 | private System.Windows.Forms.TextBox txtMessage; 469 | private System.Windows.Forms.ToolStripMenuItem tsmiCopyText; 470 | private System.Windows.Forms.ToolStripMenuItem tsmiExpandAllChildren; 471 | private System.Windows.Forms.ContextMenuStrip textContextMenu; 472 | private System.Windows.Forms.ToolStripMenuItem tsmiPaste; 473 | private System.Windows.Forms.ToolStripMenuItem tsmiClearSelection; 474 | private System.Windows.Forms.ToolStripMenuItem tsmiNavigateToTreeNode; 475 | private System.Windows.Forms.Button btnReset; 476 | private System.Windows.Forms.ToolStripMenuItem tsmiClearContent; 477 | private System.Windows.Forms.CheckBox chkHighlightingErrors; 478 | } 479 | } 480 | 481 | -------------------------------------------------------------------------------- /CodeParser.Viewer/frmMain.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 431, 17 122 | 123 | 124 | 165, 17 125 | 126 | 127 | 17, 17 128 | 129 | 130 | 330, 17 131 | 132 | 133 | 98 134 | 135 | 136 | 137 | 138 | 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 194 | IbayZyj/AAAAMgAAABsAAAAKAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 195 | AAAAAAAAAAAAAAAAAAaRSBL/06Nc/9++gf/16M3/y5hi/41CCv8AAAAGAAAAAAAAAAAAAAAAAAAABKVb 196 | H7qcVx+4AAAAOZ5dJLejYCa/AAAAKgAAABUAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 197 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaOQw7/3btw/8mTWf+NQwz/AAAABgAAAAAAAAAAAAAAAAAA 198 | AAAAAAAAAAAAFa5hIv+fWyK1smco/7RqKv+2bS3/r2oteAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 199 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaQSBH/kUgR/wAAAAYAAAAAAAAAAAAA 200 | AAAAAAAAAAAAAAAAAAAAAAAQrmEi/6lgJLcAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 201 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 202 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAirYCLBAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 203 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 204 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqxgImIAAAACAAAAAAAAAAAAAAAAAAAAAAAA 205 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 206 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 207 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///+B////AP// 208 | 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 269 | AADAPwAAgD8AAIAfAACEHwAAzn8AAP7/AAA= 270 | 271 | 272 | -------------------------------------------------------------------------------- /CodeParser.Viewer/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /CodeParser.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.902 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CodeParser", "CodeParser\CodeParser.csproj", "{FD9C0211-571B-497B-88B4-FC145E07F03C}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeParser.Viewer", "CodeParser.Viewer\CodeParser.Viewer.csproj", "{8E724F0A-1E47-45EF-918F-ED468F046289}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CodeParser.Test", "CodeParser.Test\CodeParser.Test.csproj", "{1FA3B24E-3B4A-41E6-80F4-D9FA265C47D3}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Release|Any CPU = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {FD9C0211-571B-497B-88B4-FC145E07F03C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {FD9C0211-571B-497B-88B4-FC145E07F03C}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {FD9C0211-571B-497B-88B4-FC145E07F03C}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {FD9C0211-571B-497B-88B4-FC145E07F03C}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {8E724F0A-1E47-45EF-918F-ED468F046289}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {8E724F0A-1E47-45EF-918F-ED468F046289}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {8E724F0A-1E47-45EF-918F-ED468F046289}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {8E724F0A-1E47-45EF-918F-ED468F046289}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {1FA3B24E-3B4A-41E6-80F4-D9FA265C47D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {1FA3B24E-3B4A-41E6-80F4-D9FA265C47D3}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {1FA3B24E-3B4A-41E6-80F4-D9FA265C47D3}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {1FA3B24E-3B4A-41E6-80F4-D9FA265C47D3}.Release|Any CPU.Build.0 = Release|Any CPU 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | GlobalSection(ExtensibilityGlobals) = postSolution 35 | SolutionGuid = {58260BE3-E32F-46FC-90F6-F1BBFACAC210} 36 | EndGlobalSection 37 | EndGlobal 38 | -------------------------------------------------------------------------------- /CodeParser/CodeParser.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | false 6 | victor-wiki 7 | https://github.com/victor-wiki/CodeParser 8 | Parser code generated from antlr(https://github.com/antlr/grammars-v4), the library includes C, C++, C#, Java, JavaScript, Python, Php, MySql, TSql, PlSql, Postgres and SQLite. 9 | 2.0.0 10 | make up missing files 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /CodeParser/Manager/ParserManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace CodeParser 7 | { 8 | public class ParserManager 9 | { 10 | public static List ParserInfos 11 | { 12 | get 13 | { 14 | return new List() 15 | { 16 | new ParserInfo() { ParserName = nameof(CParser), Language= "C", FileExtension = ".c", EntryRuleName =nameof(CParser.compilationUnit) }, 17 | new ParserInfo() { ParserName = nameof(CPP14Parser), Language= "C++", FileExtension = ".cpp", EntryRuleName =nameof(CPP14Parser.translationunit) }, 18 | new ParserInfo() { ParserName = nameof(CSharpParser), Language= "C#", FileExtension = ".cs", EntryRuleName =nameof(CSharpParser.compilation_unit) }, 19 | new ParserInfo() { ParserName = nameof(Java8Parser), Language= "Java8", FileExtension = ".java", EntryRuleName =nameof(Java8Parser.compilationUnit) }, 20 | new ParserInfo() { ParserName = nameof(Java9Parser), Language= "Java9", FileExtension = ".java", EntryRuleName =nameof(Java9Parser.compilationUnit) }, 21 | new ParserInfo() { ParserName = nameof(JavaScriptParser), Language= "JavaScript", FileExtension = ".js", EntryRuleName =nameof(JavaScriptParser.program) }, 22 | new ParserInfo() { ParserName = nameof(Python3Parser), Language= "Python3", FileExtension = ".py", EntryRuleName =nameof(Python3Parser.file_input)}, 23 | new ParserInfo() { ParserName = nameof(PhpParser), Language= "Php", FileExtension = ".php", EntryRuleName =nameof(PhpParser.htmlDocument) }, 24 | new ParserInfo() { ParserName = nameof(TSqlParser), Language= "TSql", FileExtension = ".sql", EntryRuleName =nameof(TSqlParser.tsql_file) }, 25 | new ParserInfo() { ParserName = nameof(MySqlParser), Language= "MySql", FileExtension = ".sql", EntryRuleName =nameof(MySqlParser.query) }, 26 | new ParserInfo() { ParserName = nameof(PlSqlParser), Language= "PlSql", FileExtension = ".sql", EntryRuleName =nameof(PlSqlParser.sql_script) }, 27 | new ParserInfo() { ParserName = nameof(PostgreSqlParser), Language= "PostgreSql", FileExtension = ".sql", EntryRuleName =nameof(PostgreSqlParser.root) }, 28 | new ParserInfo() { ParserName = nameof(SQLiteParser), Language= "SQLite", FileExtension = ".sql", EntryRuleName =nameof(SQLiteParser.parse) } 29 | }; 30 | } 31 | } 32 | 33 | public static ParserInfo GetParserInfoByName(string name) 34 | { 35 | return ParserInfos.FirstOrDefault(item => item.ParserName == name); 36 | } 37 | 38 | public static ParserInfo GetParserInfoByLanguage(string language) 39 | { 40 | return ParserInfos.FirstOrDefault(item => item.Language == language); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /CodeParser/Model/ParserInfo.cs: -------------------------------------------------------------------------------- 1 | namespace CodeParser 2 | { 3 | public class ParserInfo 4 | { 5 | public string ParserName { get; set; } 6 | public string Language { get; set; } 7 | public string FileExtension { get; set; } 8 | public string EntryRuleName { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /CodeParser/Parser/CSharp/CSharpLexerBase.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using System.Collections.Generic; 3 | using System; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text.RegularExpressions; 7 | 8 | public abstract class CSharpLexerBase : Lexer 9 | { 10 | public CSharpLexerBase(ICharStream input) 11 | : base(input) 12 | { 13 | _input = input; 14 | } 15 | 16 | public CSharpLexerBase(ICharStream input, TextWriter output, TextWriter errorOutput) 17 | : base(input, output, errorOutput) 18 | { 19 | _input = input; 20 | } 21 | 22 | private ICharStream _input; 23 | protected int interpolatedStringLevel; 24 | protected Stack interpolatedVerbatiums = new Stack(); 25 | protected Stack curlyLevels = new Stack(); 26 | protected bool verbatium; 27 | 28 | protected void OnInterpolatedRegularStringStart() 29 | { 30 | interpolatedStringLevel++; 31 | interpolatedVerbatiums.Push(false); 32 | verbatium = false; 33 | } 34 | 35 | protected void OnInterpolatedVerbatiumStringStart() 36 | { 37 | interpolatedStringLevel++; 38 | interpolatedVerbatiums.Push(true); 39 | verbatium = true; 40 | } 41 | 42 | protected void OnOpenBrace() 43 | { 44 | if (interpolatedStringLevel > 0) 45 | { 46 | curlyLevels.Push(curlyLevels.Pop() + 1); 47 | } 48 | } 49 | 50 | protected void OnCloseBrace() 51 | { 52 | if (interpolatedStringLevel > 0) 53 | { 54 | curlyLevels.Push(curlyLevels.Pop() - 1); 55 | if (curlyLevels.Peek() == 0) 56 | { 57 | curlyLevels.Pop(); 58 | Skip(); 59 | PopMode(); 60 | } 61 | } 62 | } 63 | 64 | protected void OnColon() 65 | { 66 | 67 | if (interpolatedStringLevel > 0) 68 | { 69 | int ind = 1; 70 | bool switchToFormatString = true; 71 | while ((char)_input.LA(ind) != '}') 72 | { 73 | if (_input.LA(ind) == ':' || _input.LA(ind) == ')') 74 | { 75 | switchToFormatString = false; 76 | break; 77 | } 78 | ind++; 79 | } 80 | if (switchToFormatString) 81 | { 82 | this.Mode(CSharpLexer.INTERPOLATION_FORMAT); 83 | } 84 | } 85 | } 86 | 87 | protected void OpenBraceInside() 88 | { 89 | curlyLevels.Push(1); 90 | } 91 | 92 | protected void OnDoubleQuoteInside() 93 | { 94 | interpolatedStringLevel--; 95 | interpolatedVerbatiums.Pop(); 96 | verbatium = (interpolatedVerbatiums.Count() > 0 ? interpolatedVerbatiums.Peek() : false); 97 | } 98 | 99 | protected void OnCloseBraceInside() 100 | { 101 | curlyLevels.Pop(); 102 | } 103 | 104 | protected bool IsRegularCharInside() 105 | { 106 | return !verbatium; 107 | } 108 | 109 | protected bool IsVerbatiumDoubleQuoteInside() 110 | { 111 | return verbatium; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /CodeParser/Parser/CSharp/CSharpParserBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using Antlr4.Runtime; 5 | 6 | public abstract class CSharpParserBase : Parser 7 | { 8 | protected CSharpParserBase(ITokenStream input) 9 | : base(input) 10 | { 11 | } 12 | 13 | protected CSharpParserBase(ITokenStream input, TextWriter output, TextWriter errorOutput) 14 | : base(input, output, errorOutput) 15 | { 16 | } 17 | 18 | protected bool IsLocalVariableDeclaration() 19 | { 20 | var local_var_decl = this.Context as CSharpParser.Local_variable_declarationContext; 21 | if (local_var_decl == null) return true; 22 | var local_variable_type = local_var_decl.local_variable_type(); 23 | if (local_variable_type == null) return true; 24 | if (local_variable_type.GetText() == "var") return false; 25 | return true; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /CodeParser/Parser/Java/Java9LexerBase.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2014 Terence Parr 4 | * Copyright (c) 2014 Sam Harwell 5 | * Copyright (c) 2017 Chan Chung Kwong 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright 13 | * notice, this list of conditions and the following disclaimer. 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in the 16 | * documentation and/or other materials provided with the distribution. 17 | * 3. The name of the author may not be used to endorse or promote products 18 | * derived from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | using Antlr4.Runtime; 33 | using System; 34 | using System.IO; 35 | using System.Linq; 36 | using System.Text.RegularExpressions; 37 | 38 | public abstract class Java9LexerBase : Lexer 39 | { 40 | private readonly ICharStream _input; 41 | 42 | protected Java9LexerBase(ICharStream input, TextWriter output, TextWriter errorOutput) 43 | : base(input, output, errorOutput) { 44 | _input = input; 45 | } 46 | 47 | private class Character 48 | { 49 | public static bool isJavaIdentifierPart(int c) 50 | { 51 | if (Char.IsLetter((char)c)) 52 | return true; 53 | else if (c == (int)'$') 54 | return true; 55 | else if (c == (int)'_') 56 | return true; 57 | else if (Char.IsDigit((char)c)) 58 | return true; 59 | else if (Char.IsNumber((char)c)) 60 | return true; 61 | return false; 62 | } 63 | 64 | public static bool isJavaIdentifierStart(int c) 65 | { 66 | if (Char.IsLetter((char)c)) 67 | return true; 68 | else if (c == (int)'$') 69 | return true; 70 | else if (c == (int)'_') 71 | return true; 72 | return false; 73 | } 74 | 75 | public static int toCodePoint(int high, int low) 76 | { 77 | return Char.ConvertToUtf32((char)high, (char)low); 78 | } 79 | } 80 | 81 | public bool Check1() 82 | { 83 | return Character.isJavaIdentifierStart(_input.LA(-1)); 84 | } 85 | 86 | public bool Check2() 87 | { 88 | return Character.isJavaIdentifierStart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1))); 89 | } 90 | 91 | public bool Check3() 92 | { 93 | return Character.isJavaIdentifierPart(_input.LA(-1)); 94 | } 95 | 96 | public bool Check4() 97 | { 98 | return Character.isJavaIdentifierPart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1))); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /CodeParser/Parser/JavaScript/JavaScriptLexerBase.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using static JavaScriptParser; 5 | 6 | /// 7 | /// All lexer methods that used in grammar (IsStrictMode) 8 | /// should start with Upper Case Char similar to Lexer rules. 9 | /// 10 | public abstract class JavaScriptLexerBase : Lexer 11 | { 12 | /// 13 | /// Stores values of nested modes. By default mode is strict or 14 | /// defined externally(useStrictDefault) 15 | /// 16 | private Stack scopeStrictModes = new Stack(); 17 | 18 | private IToken _lastToken = null; 19 | 20 | /// 21 | /// Default value of strict mode 22 | /// Can be defined externally by changing UseStrictDefault 23 | /// 24 | private bool _useStrictDefault = false; 25 | 26 | /// 27 | /// Current value of strict mode 28 | /// Can be defined during parsing, see StringFunctions.js and StringGlobal.js samples 29 | /// 30 | private bool _useStrictCurrent = false; 31 | 32 | /// 33 | /// Keeps track of the the current depth of nested template string backticks. 34 | /// E.g. after the X in: 35 | /// 36 | /// `${a ? `${X 37 | /// 38 | /// templateDepth will be 2. This variable is needed to determine if a `}` is a 39 | /// plain CloseBrace, or one that closes an expression inside a template string. 40 | /// 41 | private int _templateDepth = 0; 42 | 43 | public JavaScriptLexerBase(ICharStream input) 44 | : base(input) 45 | { 46 | } 47 | 48 | public JavaScriptLexerBase(ICharStream input, TextWriter output, TextWriter errorOutput) : this(input) 49 | { 50 | } 51 | 52 | public bool IsStartOfFile(){ 53 | return _lastToken == null; 54 | } 55 | 56 | public bool UseStrictDefault 57 | { 58 | get 59 | { 60 | return _useStrictDefault; 61 | } 62 | set 63 | { 64 | _useStrictDefault = value; 65 | _useStrictCurrent = value; 66 | } 67 | } 68 | 69 | public bool IsStrictMode() 70 | { 71 | return _useStrictCurrent; 72 | } 73 | 74 | public bool IsInTemplateString() 75 | { 76 | return _templateDepth > 0; 77 | } 78 | 79 | /// 80 | /// Return the next token from the character stream and records this last 81 | /// token in case it resides on the default channel. This recorded token 82 | /// is used to determine when the lexer could possibly match a regex 83 | /// literal. 84 | /// 85 | /// 86 | /// 87 | /// The next token from the character stream. 88 | /// 89 | public override IToken NextToken() 90 | { 91 | // Get the next token. 92 | IToken next = base.NextToken(); 93 | 94 | if (next.Channel == DefaultTokenChannel) 95 | { 96 | // Keep track of the last token on the default channel. 97 | _lastToken = next; 98 | } 99 | 100 | return next; 101 | } 102 | 103 | protected void ProcessOpenBrace() 104 | { 105 | _useStrictCurrent = scopeStrictModes.Count > 0 && scopeStrictModes.Peek() ? true : UseStrictDefault; 106 | scopeStrictModes.Push(_useStrictCurrent); 107 | } 108 | 109 | protected void ProcessCloseBrace() 110 | { 111 | _useStrictCurrent = scopeStrictModes.Count > 0 ? scopeStrictModes.Pop() : UseStrictDefault; 112 | } 113 | 114 | protected void ProcessStringLiteral() 115 | { 116 | if (_lastToken == null || _lastToken.Type == OpenBrace) 117 | { 118 | if (Text.Equals("\"use strict\"") || Text.Equals("'use strict'")) 119 | { 120 | if (scopeStrictModes.Count > 0) 121 | scopeStrictModes.Pop(); 122 | _useStrictCurrent = true; 123 | scopeStrictModes.Push(_useStrictCurrent); 124 | } 125 | } 126 | } 127 | 128 | public void IncreaseTemplateDepth() 129 | { 130 | _templateDepth++; 131 | } 132 | 133 | public void DecreaseTemplateDepth() 134 | { 135 | _templateDepth--; 136 | } 137 | 138 | /// 139 | /// Returns true if the lexer can match a regex literal. 140 | /// 141 | protected bool IsRegexPossible() 142 | { 143 | if (_lastToken == null) 144 | { 145 | // No token has been produced yet: at the start of the input, 146 | // no division is possible, so a regex literal _is_ possible. 147 | return true; 148 | } 149 | 150 | switch (_lastToken.Type) 151 | { 152 | case Identifier: 153 | case NullLiteral: 154 | case BooleanLiteral: 155 | case This: 156 | case CloseBracket: 157 | case CloseParen: 158 | case OctalIntegerLiteral: 159 | case DecimalLiteral: 160 | case HexIntegerLiteral: 161 | case StringLiteral: 162 | case PlusPlus: 163 | case MinusMinus: 164 | // After any of the tokens above, no regex literal can follow. 165 | return false; 166 | default: 167 | // In all other cases, a regex literal _is_ possible. 168 | return true; 169 | } 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /CodeParser/Parser/JavaScript/JavaScriptParserBase.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using static JavaScriptParser; 5 | 6 | /// 7 | /// All parser methods that used in grammar (p, prev, notLineTerminator, etc.) 8 | /// should start with lower case char similar to parser rules. 9 | /// 10 | public abstract class JavaScriptParserBase : Parser 11 | { 12 | private readonly Stack _tagNames = new Stack(); 13 | public JavaScriptParserBase(ITokenStream input) 14 | : base(input) 15 | { 16 | } 17 | 18 | public JavaScriptParserBase(ITokenStream input, TextWriter output, TextWriter errorOutput) : this(input) 19 | { 20 | } 21 | 22 | /// 23 | /// Short form for prev(String str) 24 | /// 25 | protected bool p(string str) 26 | { 27 | return prev(str); 28 | } 29 | 30 | /// 31 | /// Whether the previous token value equals to str 32 | /// 33 | protected bool prev(string str) 34 | { 35 | return ((ITokenStream)this.InputStream).LT(-1).Text.Equals(str); 36 | } 37 | 38 | // Short form for next(String str) 39 | protected bool n(string str) 40 | { 41 | return next(str); 42 | } 43 | 44 | // Whether the next token value equals to @param str 45 | protected bool next(string str) 46 | { 47 | return ((ITokenStream)this.InputStream).LT(1).Text.Equals(str); 48 | } 49 | 50 | protected bool notLineTerminator() 51 | { 52 | return !here(LineTerminator); 53 | } 54 | 55 | protected bool notOpenBraceAndNotFunction() 56 | { 57 | int nextTokenType = ((ITokenStream)this.InputStream).LT(1).Type; 58 | return nextTokenType != OpenBrace && nextTokenType != Function_; 59 | } 60 | 61 | protected bool closeBrace() 62 | { 63 | return ((ITokenStream)this.InputStream).LT(1).Type == CloseBrace; 64 | } 65 | 66 | /// Returns true if on the current index of the parser's 67 | /// token stream a token of the given type exists on the 68 | /// Hidden channel. 69 | /// 70 | /// 71 | /// The type of the token on the Hidden channel to check. 72 | /// 73 | protected bool here(int type) 74 | { 75 | // Get the token ahead of the current index. 76 | int possibleIndexEosToken = CurrentToken.TokenIndex - 1; 77 | IToken ahead = ((ITokenStream)this.InputStream).Get(possibleIndexEosToken); 78 | 79 | // Check if the token resides on the Hidden channel and if it's of the 80 | // provided type. 81 | return ahead.Channel == Lexer.Hidden && ahead.Type == type; 82 | } 83 | 84 | /// 85 | /// Returns true if on the current index of the parser's 86 | /// token stream a token exists on the Hidden channel which 87 | /// either is a line terminator, or is a multi line comment that 88 | /// contains a line terminator. 89 | /// 90 | protected bool lineTerminatorAhead() 91 | { 92 | // Get the token ahead of the current index. 93 | int possibleIndexEosToken = CurrentToken.TokenIndex - 1; 94 | IToken ahead = ((ITokenStream)this.InputStream).Get(possibleIndexEosToken); 95 | 96 | if (ahead.Channel != Lexer.Hidden) 97 | { 98 | // We're only interested in tokens on the Hidden channel. 99 | return false; 100 | } 101 | 102 | if (ahead.Type == LineTerminator) 103 | { 104 | // There is definitely a line terminator ahead. 105 | return true; 106 | } 107 | 108 | if (ahead.Type == WhiteSpaces) 109 | { 110 | // Get the token ahead of the current whitespaces. 111 | possibleIndexEosToken = CurrentToken.TokenIndex - 2; 112 | ahead = ((ITokenStream)this.InputStream).Get(possibleIndexEosToken); 113 | } 114 | 115 | // Get the token's text and type. 116 | string text = ahead.Text; 117 | int type = ahead.Type; 118 | 119 | // Check if the token is, or contains a line terminator. 120 | return (type == MultiLineComment && (text.Contains("\r") || text.Contains("\n"))) || 121 | (type == LineTerminator); 122 | } 123 | 124 | protected void pushHtmlTagName(string tagName) 125 | { 126 | _tagNames.Push(tagName); 127 | } 128 | 129 | protected bool popHtmlTagName(string tagName) 130 | { 131 | return string.Equals(_tagNames.Pop(),tagName, System.StringComparison.InvariantCulture); 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /CodeParser/Parser/LexerDispatchingErrorListener.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using System.IO; 3 | 4 | class LexerDispatchingErrorListener : IAntlrErrorListener 5 | { 6 | Lexer _parent; 7 | 8 | public LexerDispatchingErrorListener(Lexer parent) 9 | { 10 | _parent = parent; 11 | } 12 | 13 | public void SyntaxError(TextWriter output, IRecognizer recognizer, int offendingSymbol, int line, int charPositionInLine, string msg, RecognitionException e) 14 | { 15 | var foo = new ProxyErrorListener(_parent.ErrorListeners); 16 | foo.SyntaxError(output, recognizer, offendingSymbol, line, charPositionInLine, msg, e); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /CodeParser/Parser/MySql/IMySqlRecognizerCommon.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using Antlr4.Runtime.Tree; 3 | 4 | public interface IMySqlRecognizerCommon 5 | { 6 | int serverVersion { get; set; } 7 | MySqlMode sqlMode { get; set; } 8 | 9 | IParseTree contextFromPosition(IParseTree root, int position); 10 | string dumpTree(RuleContext context, IVocabulary vocabulary); 11 | IParseTree getNext(IParseTree tree); 12 | IParseTree getNextSibling(IParseTree tree); 13 | IParseTree getPrevious(IParseTree tree); 14 | IParseTree getPreviousSibling(IParseTree tree); 15 | bool isSqlModeActive(MySqlMode mode); 16 | bool isSqlModeActive(int mode); 17 | string sourceTextForContext(ParserRuleContext ctx, bool keepQuotes); 18 | string sourceTextForRange(IParseTree start, IParseTree stop, bool keepQuotes); 19 | string sourceTextForRange(IToken start, IToken stop, bool keepQuotes); 20 | void sqlModeFromString(string modes); 21 | } -------------------------------------------------------------------------------- /CodeParser/Parser/MySql/MySqlBaseLexer.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | 6 | public abstract class MySqlBaseLexer: Lexer 7 | { 8 | public HashSet charsets; 9 | public bool inVersionComment; 10 | private List _pendingTokens; 11 | private Dictionary _symbols; 12 | public MySqlMode sqlMode { get => mySqlRecognizerCommon.sqlMode; set => mySqlRecognizerCommon.sqlMode = value; } 13 | 14 | protected IMySqlRecognizerCommon mySqlRecognizerCommon; 15 | public int serverVersion { get => mySqlRecognizerCommon.serverVersion; set => mySqlRecognizerCommon.serverVersion = value; } 16 | 17 | public MySqlBaseLexer( 18 | ICharStream input, 19 | TextWriter output, 20 | TextWriter errorOutput, 21 | IMySqlRecognizerCommon mySqlRecognizerCommon = null 22 | ) : base(input, output, errorOutput) 23 | { 24 | charsets = new HashSet(); 25 | _pendingTokens = new List(); 26 | this.mySqlRecognizerCommon = mySqlRecognizerCommon ?? new MySqlRecognizerCommon(); 27 | } 28 | 29 | public MySqlBaseLexer(ICharStream input, IMySqlRecognizerCommon mySqlRecognizerCommon = null) : base(input) 30 | { 31 | this.mySqlRecognizerCommon = mySqlRecognizerCommon ?? new MySqlRecognizerCommon(); 32 | charsets = new HashSet(); 33 | _symbols = new Dictionary(); 34 | serverVersion = 0; 35 | sqlMode = MySqlMode.NoMode; 36 | inVersionComment = false; 37 | } 38 | 39 | protected void emitDot() 40 | { 41 | _pendingTokens.Add(this.TokenFactory.Create( 42 | new Tuple(this, this.InputStream as ICharStream), 43 | MySqlLexer.DOT_SYMBOL, 44 | this.Text, 45 | this.Channel, 46 | TokenStartCharIndex, 47 | TokenStartCharIndex, 48 | TokenStartLine, 49 | TokenStartLine //tokenStartCharPositionInLine 50 | )); 51 | 52 | Skip(); //TokenStartCharIndex = TokenStartCharIndex + 1; 53 | } 54 | 55 | protected int determineFunction(int proposed) 56 | { 57 | // Skip any whitespace character if the sql mode says they should be ignored, 58 | // before actually trying to match the open parenthesis. 59 | if (isSqlModeActive((int)MySqlMode.IgnoreSpace)) 60 | { 61 | int input = this.InputStream.LA(1); 62 | while (input == ' ' || input == '\t' || input == '\r' || input == '\n') 63 | { 64 | this.Interpreter.Consume(this.InputStream as ICharStream); 65 | this.Channel = Lexer.Hidden; 66 | this.Type = MySqlLexer.WHITESPACE; 67 | input = this.InputStream.LA(1); 68 | } 69 | } 70 | 71 | return this.InputStream.LA(1) == '(' ? proposed : MySqlLexer.IDENTIFIER; 72 | } 73 | 74 | protected int determineNumericType(string text) 75 | { 76 | const string long_str = "2147483647"; 77 | const int long_len = 10; 78 | const string signed_long_str = "-2147483648"; 79 | const string longlong_str = "9223372036854775807"; 80 | const int longlong_len = 19; 81 | const string signed_longlong_str = "-9223372036854775808"; 82 | const int signed_longlong_len = 19; 83 | const string unsigned_longlong_str = "18446744073709551615"; 84 | const int unsigned_longlong_len = 20; 85 | 86 | // The original code checks for leading +/- but actually that can never happen, neither in the 87 | // server parser (as a digit is used to trigger processing in the lexer) nor in our parser 88 | // as our rules are defined without signs. But we do it anyway for maximum compatibility. 89 | int length = text.Length - 1; 90 | var strIndex = 0; 91 | if (length < long_len) // quick normal case 92 | return MySqlLexer.INT_NUMBER; 93 | int negative = 0; 94 | 95 | if (text[strIndex] == '+') // Remove sign and pre-zeros 96 | { 97 | strIndex++; 98 | length--; 99 | } 100 | else if (text[strIndex] == '-') 101 | { 102 | strIndex++; 103 | length--; 104 | negative = 1; 105 | } 106 | 107 | while (text[strIndex] == '0' && length != 0) 108 | { 109 | strIndex++; 110 | length--; 111 | } 112 | 113 | if (length < long_len) 114 | return MySqlLexer.INT_NUMBER; 115 | 116 | int smaller, bigger; 117 | int cmpIndex = 0; 118 | string cmp = string.Empty; 119 | if (negative != 0) 120 | { 121 | if (length == long_len) 122 | { 123 | cmp = signed_long_str + 1; 124 | smaller = MySqlLexer.INT_NUMBER; // If <= signed_long_str 125 | bigger = MySqlLexer.LONG_NUMBER; // If >= signed_long_str 126 | } 127 | else if (length < signed_longlong_len) 128 | return MySqlLexer.LONG_NUMBER; 129 | else if (length > signed_longlong_len) 130 | return MySqlLexer.DECIMAL_NUMBER; 131 | else 132 | { 133 | cmp = signed_longlong_str + 1; 134 | smaller = MySqlLexer.LONG_NUMBER; // If <= signed_longlong_str 135 | bigger = MySqlLexer.DECIMAL_NUMBER; 136 | } 137 | } 138 | else 139 | { 140 | if (length == long_len) 141 | { 142 | cmp = long_str; 143 | smaller = MySqlLexer.INT_NUMBER; 144 | bigger = MySqlLexer.LONG_NUMBER; 145 | } 146 | else if (length < longlong_len) 147 | return MySqlLexer.LONG_NUMBER; 148 | else if (length > longlong_len) 149 | { 150 | if (length > unsigned_longlong_len) 151 | return MySqlLexer.DECIMAL_NUMBER; 152 | cmp = unsigned_longlong_str; 153 | smaller = MySqlLexer.ULONGLONG_NUMBER; 154 | bigger = MySqlLexer.DECIMAL_NUMBER; 155 | } 156 | else 157 | { 158 | cmp = longlong_str; 159 | smaller = MySqlLexer.LONG_NUMBER; 160 | bigger = MySqlLexer.ULONGLONG_NUMBER; 161 | } 162 | } 163 | 164 | while (!string.IsNullOrEmpty(cmp) && cmpIndex++ == strIndex++) 165 | ; 166 | 167 | //return ((unsigned char)strIndex[-1] <= (unsigned char)cmpIndex[-1]) ? smaller: bigger; 168 | return (text[strIndex - 1] <= text[cmpIndex - 1]) ? smaller : bigger; 169 | } 170 | 171 | private bool VERSION_COMMENT_START_sempred(RuleContext _localctx, int predIndex) { 172 | switch (predIndex) { 173 | case 151: return checkVersion(getText()); 174 | } 175 | return true; 176 | } 177 | 178 | protected bool checkVersion(string text) 179 | { 180 | if (text.Length < 8) // Minimum is: /*!12345 181 | return false; 182 | 183 | // Skip version comment introducer. 184 | long version = long.Parse(text.Substring(3)); 185 | if (version <= serverVersion) 186 | { 187 | inVersionComment = true; 188 | return true; 189 | } 190 | return false; 191 | } 192 | 193 | protected int checkCharset(string text) 194 | { 195 | //return charsets.Count > 0 ? MySqlLexer.UNDERSCORE_CHARSET : MySqlLexer.IDENTIFIER; 196 | return charsets.Contains(text) ? MySqlLexer.UNDERSCORE_CHARSET : MySqlLexer.IDENTIFIER; 197 | 198 | } 199 | 200 | public bool isSqlModeActive(MySqlMode mode) => isSqlModeActive((int)mode); 201 | 202 | public bool isSqlModeActive(int mode) => mySqlRecognizerCommon.isSqlModeActive(mode); 203 | 204 | public void setType(int type) => this.Type = type; 205 | public int getType() => this.Type; 206 | 207 | public void setText(string text) => this.Text = text; 208 | public string getText() => this.Text; 209 | } -------------------------------------------------------------------------------- /CodeParser/Parser/MySql/MySqlBaseRecognizer.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using Antlr4.Runtime.Tree; 3 | using System.IO; 4 | using System.Text; 5 | 6 | public abstract class MySqlBaseRecognizer : Antlr4.Runtime.Parser, IMySqlRecognizerCommon 7 | { 8 | #region IMySqlRecognizerCommon 9 | 10 | protected IMySqlRecognizerCommon mySqlRecognizerCommon = new MySqlRecognizerCommon(); 11 | 12 | public int serverVersion { get => mySqlRecognizerCommon.serverVersion; set => mySqlRecognizerCommon.serverVersion = value; } 13 | public MySqlMode sqlMode { get => mySqlRecognizerCommon.sqlMode; set => mySqlRecognizerCommon.sqlMode = value; } 14 | 15 | public IParseTree contextFromPosition(IParseTree root, int position) => mySqlRecognizerCommon.contextFromPosition(root, position); 16 | 17 | public string dumpTree(RuleContext context, IVocabulary vocabulary) => mySqlRecognizerCommon.dumpTree(context, vocabulary); 18 | 19 | public IParseTree getNext(IParseTree tree) => mySqlRecognizerCommon.getNext(tree); 20 | 21 | public IParseTree getNextSibling(IParseTree tree) => mySqlRecognizerCommon.getNextSibling(tree); 22 | 23 | public IParseTree getPrevious(IParseTree tree) => mySqlRecognizerCommon.getPrevious(tree); 24 | 25 | public IParseTree getPreviousSibling(IParseTree tree) => mySqlRecognizerCommon.getPreviousSibling(tree); 26 | 27 | public bool isSqlModeActive(MySqlMode mode) => isSqlModeActive((int)mode); 28 | 29 | public bool isSqlModeActive(int mode) => mySqlRecognizerCommon.isSqlModeActive(mode); 30 | 31 | public string sourceTextForContext(ParserRuleContext ctx, bool keepQuotes) => mySqlRecognizerCommon.sourceTextForContext(ctx, keepQuotes); 32 | 33 | public string sourceTextForRange(IParseTree start, IParseTree stop, bool keepQuotes) => mySqlRecognizerCommon.sourceTextForRange(start, stop, keepQuotes); 34 | 35 | public string sourceTextForRange(IToken start, IToken stop, bool keepQuotes) => mySqlRecognizerCommon.sourceTextForRange(start, stop, keepQuotes); 36 | 37 | public void sqlModeFromString(string modes) => mySqlRecognizerCommon.sqlModeFromString(modes); 38 | #endregion 39 | 40 | public MySqlBaseRecognizer(Antlr4.Runtime.ITokenStream input, IMySqlRecognizerCommon mySqlRecognizerCommon = null) : base(input) 41 | { this.mySqlRecognizerCommon = mySqlRecognizerCommon ?? new MySqlRecognizerCommon(); } 42 | 43 | public MySqlBaseRecognizer(ITokenStream input, TextWriter output, TextWriter errorOutput, IMySqlRecognizerCommon mySqlRecognizerCommon = null) : base(input, output, errorOutput) 44 | { this.mySqlRecognizerCommon = mySqlRecognizerCommon ?? new MySqlRecognizerCommon(); } 45 | 46 | public static string getText(Antlr4.Runtime.RuleContext context, bool convertEscapes) 47 | { 48 | var result = new StringBuilder(); 49 | if (context is MySqlParser.TextLiteralContext textLiteralContext && textLiteralContext != null) 50 | { 51 | var list = textLiteralContext.textStringLiteral(); 52 | var lastType = Antlr4.Runtime.TokenConstants.InvalidType; 53 | var lastIndex = MySqlParsersCommon.InvalidIndex; 54 | foreach (var entry in list) 55 | { 56 | var token = entry.value; 57 | switch (token.Type) 58 | { 59 | case MySqlParser.DOUBLE_QUOTED_TEXT: 60 | case MySqlParser.SINGLE_QUOTED_TEXT: 61 | var text = token.Text; 62 | var quoteChar = text[0]; 63 | var doubledQuoteChar = new string(quoteChar, 2); 64 | if (lastType == token.Type && lastIndex + 1 == token.TokenIndex) 65 | { 66 | result.Append(quoteChar); 67 | } 68 | lastType = token.Type; 69 | lastIndex = token.TokenIndex; 70 | 71 | text = text.Substring(1, text.Length - 2); 72 | int position = text.IndexOf(doubledQuoteChar); 73 | if (position >= 0) 74 | { text = text.Replace(doubledQuoteChar, quoteChar.ToString()); } 75 | result.Append(text); 76 | break; 77 | } 78 | } 79 | if (convertEscapes) 80 | { 81 | var temp = result.ToString(); 82 | result.Clear(); 83 | var pendingEscape = false; 84 | for (int ci = 0; ci < temp.Length; ci++) 85 | { 86 | var c = temp[ci]; 87 | if (pendingEscape) 88 | { 89 | pendingEscape = false; 90 | switch (c) 91 | { 92 | case 'n': 93 | c = '\n'; 94 | break; 95 | case 't': 96 | c = '\t'; 97 | break; 98 | case 'r': 99 | c = '\r'; 100 | break; 101 | case 'b': 102 | c = '\b'; 103 | break; 104 | case '0': 105 | c = '\u0000'; 106 | break; // ASCII null 107 | case 'Z': 108 | c = '\u0032'; 109 | break; // Win32 end of file 110 | } 111 | } 112 | else if (c == '\\') 113 | { 114 | pendingEscape = true; 115 | continue; 116 | } 117 | result.Append(c); 118 | } 119 | 120 | if (pendingEscape) 121 | { result.Append("\\"); } 122 | } 123 | return result.ToString(); 124 | } 125 | 126 | return context.GetText(); 127 | } 128 | 129 | public bool look(int position, int expected) 130 | { 131 | return this.InputStream.LA(position) == expected; 132 | } 133 | 134 | public bool containsLinebreak(string text) 135 | { 136 | return text.Contains("\r\n"); 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /CodeParser/Parser/MySql/MySqlMode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | [Flags] 4 | public enum MySqlMode : int 5 | { 6 | NoMode = 0, 7 | AnsiQuotes = 1 << 0, 8 | HighNotPrecedence = 1 << 1, 9 | PipesAsConcat = 1 << 2, 10 | IgnoreSpace = 1 << 3, 11 | NoBackslashEscapes = 1 << 4 12 | } -------------------------------------------------------------------------------- /CodeParser/Parser/MySql/MySqlParsersCommon.cs: -------------------------------------------------------------------------------- 1 | public static class MySqlParsersCommon 2 | { 3 | public static int InvalidIndex = int.MaxValue; 4 | } 5 | -------------------------------------------------------------------------------- /CodeParser/Parser/MySql/MySqlRecognizerCommon.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using Antlr4.Runtime.Tree; 3 | using System; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | public class MySqlRecognizerCommon : IMySqlRecognizerCommon 8 | { 9 | public int serverVersion { get; set; } 10 | public MySqlMode sqlMode { get; set; } 11 | 12 | public MySqlRecognizerCommon(int serverVersion = MySqlServerVersion.MAX_SERVER_VERSION, MySqlMode sqlMode = MySqlMode.NoMode) 13 | { 14 | this.sqlMode = sqlMode; 15 | this.serverVersion = serverVersion; 16 | } 17 | 18 | public bool isSqlModeActive(MySqlMode mode) => isSqlModeActive((int)mode); 19 | 20 | public bool isSqlModeActive(int mode) 21 | { 22 | return ((int)sqlMode & mode) != 0; 23 | } 24 | 25 | public void sqlModeFromString(string modes) 26 | { 27 | sqlMode = MySqlMode.NoMode; 28 | modes = modes.ToUpperInvariant(); 29 | foreach (var mode in modes.Split(',').Select(m => m.Trim())) 30 | { 31 | if (mode == "ANSI" || mode == "DB2" || mode == "MAXDB" || mode == "MSSQL" || mode == "ORACLE" || mode == "POSTGRESQL") 32 | sqlMode = sqlMode | MySqlMode.AnsiQuotes | MySqlMode.PipesAsConcat | MySqlMode.IgnoreSpace; 33 | else if (mode == "ANSI_QUOTES") 34 | sqlMode = sqlMode | MySqlMode.AnsiQuotes; 35 | else if (mode == "PIPES_AS_CONCAT") 36 | sqlMode = sqlMode | MySqlMode.PipesAsConcat; 37 | else if (mode == "NO_BACKSLASH_ESCAPES") 38 | sqlMode = sqlMode | MySqlMode.NoBackslashEscapes; 39 | else if (mode == "IGNORE_SPACE") 40 | sqlMode = sqlMode | MySqlMode.IgnoreSpace; 41 | else if (mode == "HIGH_NOT_PRECEDENCE" || mode == "mySql323" || mode == "mySql40") 42 | sqlMode = sqlMode | MySqlMode.HighNotPrecedence; 43 | } 44 | } 45 | 46 | public static string dumpTree(RuleContext context, IVocabulary vocabulary, string indentation = "") 47 | { 48 | var stream = new StringBuilder(); 49 | for (int index = 0; index < context.ChildCount; index++) 50 | { 51 | IParseTree child = context.GetChild(index); 52 | if (child is RuleContext ruleContext && ruleContext != null) 53 | { 54 | if (child is MySqlParser.TextLiteralContext textLiteralContext && textLiteralContext != null) 55 | { 56 | var interval = ruleContext.SourceInterval; 57 | stream.Append($"{indentation}(index range: {interval.a}..{interval.b}, string literal) {MySqlBaseRecognizer.getText(ruleContext, true)} {Environment.NewLine} "); 58 | } 59 | else 60 | { 61 | stream.Append(dumpTree(ruleContext, vocabulary, indentation.Length < 100 ? $"{indentation} " : indentation)); 62 | } 63 | } 64 | else 65 | { 66 | stream.Append(indentation); 67 | var node = child as ITerminalNode; 68 | if (child is IErrorNode errorNode) 69 | { 70 | stream.Append("Syntax Error: "); 71 | var token = node.Symbol; 72 | var type = token.Type; 73 | var tokenName = type == TokenConstants.EOF ? "" : vocabulary.GetSymbolicName(token.Type); 74 | stream.Append($"(line: {token.Line}, offset: {token.Column}, index: {token.TokenIndex}, {tokenName} [{token.Type}]) {token.Text}{Environment.NewLine}"); 75 | } 76 | } 77 | } 78 | return stream.ToString(); 79 | } 80 | 81 | public string dumpTree(RuleContext context, IVocabulary vocabulary) 82 | { 83 | return dumpTree(context, vocabulary, ""); 84 | } 85 | 86 | public string sourceTextForContext(ParserRuleContext ctx, bool keepQuotes) 87 | { 88 | return sourceTextForRange(ctx.Start, ctx.Stop, keepQuotes); 89 | } 90 | 91 | public string sourceTextForRange(Antlr4.Runtime.Tree.IParseTree start, Antlr4.Runtime.Tree.IParseTree stop, bool keepQuotes) 92 | { 93 | IToken startToken = start is ITerminalNode ? (start as ITerminalNode).Symbol : (start as ParserRuleContext).Start; 94 | IToken stopToken = stop is ITerminalNode ? (stop as ITerminalNode).Symbol : (stop as ParserRuleContext).Stop; 95 | return sourceTextForRange(startToken, stopToken, keepQuotes); 96 | } 97 | 98 | public string sourceTextForRange(IToken start, IToken stop, bool keepQuotes) 99 | { 100 | ICharStream cs = start.TokenSource.InputStream; 101 | int stopIndex = stop != null ? stop.StopIndex : int.MaxValue; 102 | string result = cs.GetText(new Antlr4.Runtime.Misc.Interval(start.StartIndex, stopIndex)); 103 | if (keepQuotes || result.Length < 2) 104 | return result; 105 | 106 | char quoteChar = result[0]; 107 | if ((quoteChar == '"' || quoteChar == '`' || quoteChar == '\'') && quoteChar == result.LastOrDefault()) 108 | { 109 | if (quoteChar == '"' || quoteChar == '\'') 110 | { 111 | // Replace any double occurence of the quote char by a single one. 112 | result = result.Replace(new string(quoteChar, 2), new string(quoteChar, 1)); 113 | } 114 | 115 | return result.Substring(1, result.Length - 2); 116 | } 117 | 118 | return result; 119 | } 120 | 121 | public IParseTree getPreviousSibling(IParseTree tree) 122 | { 123 | IParseTree parent = tree.Parent; 124 | if (parent == null) 125 | return default(IParseTree); 126 | 127 | 128 | if (parent.ChildCount == 0 || parent.GetChild(0) == tree) 129 | return null; 130 | 131 | var children = Enumerable.Range(0, parent.ChildCount).Select(i => parent.GetChild(i)); 132 | for (int childIndex = 0; childIndex < parent.ChildCount; childIndex++) 133 | { 134 | if (parent.GetChild(childIndex) == tree) 135 | { 136 | return parent.GetChild(childIndex - 1); 137 | } 138 | } 139 | return default(IParseTree); 140 | } 141 | 142 | public IParseTree getPrevious(IParseTree tree) 143 | { 144 | do 145 | { 146 | IParseTree sibling = getPreviousSibling(tree); 147 | if (sibling != null) 148 | { 149 | if (sibling is ITerminalNode terminalNode && terminalNode != null) 150 | return sibling; 151 | 152 | tree = sibling; 153 | 154 | while (tree.ChildCount > 0) 155 | tree = tree.GetChild(tree.ChildCount - 1); 156 | if (tree is ITerminalNode) 157 | return tree; 158 | } 159 | else 160 | tree = tree.Parent; 161 | } while (tree != null); 162 | 163 | return null; 164 | } 165 | 166 | public IParseTree getNextSibling(IParseTree tree) 167 | { 168 | IParseTree parent = tree.Parent; 169 | if (parent == null) 170 | return null; 171 | 172 | if (parent.ChildCount == 0 || parent.GetChild(parent.ChildCount - 1) == tree) 173 | return null; 174 | 175 | for (int childIndex = 0; childIndex < parent.ChildCount; childIndex++) 176 | { 177 | var iterator = parent.GetChild(childIndex); 178 | if (iterator == tree) 179 | { 180 | return parent.GetChild(childIndex + 1); 181 | } 182 | } 183 | 184 | return null; // We actually never arrive here, but compilers want to be silenced. 185 | } 186 | 187 | public IParseTree getNext(IParseTree tree) 188 | { 189 | // If we have children return the first one. 190 | if (tree.ChildCount > 0) 191 | { 192 | do 193 | { 194 | tree = tree.GetChild(0); 195 | } while (tree.ChildCount > 0); 196 | return tree; 197 | } 198 | 199 | // No children, so try our next sibling (or that of our parent(s)). 200 | do 201 | { 202 | IParseTree sibling = getNextSibling(tree); 203 | if (sibling != null) 204 | { 205 | if (sibling is ITerminalNode) 206 | return sibling; 207 | return getNext(sibling); 208 | } 209 | tree = tree.Parent; 210 | } while (tree != null); 211 | 212 | return null; 213 | } 214 | 215 | IParseTree terminalFromPosition(IParseTree root, (int first, int second) position) 216 | { 217 | do 218 | { 219 | root = getNext(root); 220 | if (root is ITerminalNode) 221 | { 222 | IToken token = (root as ITerminalNode)?.Symbol; 223 | if (token.Type == TokenConstants.EOF) 224 | return getPrevious(root); 225 | 226 | // If we reached a position after the given one then we found a situation 227 | // where that position is between two terminals. Return the previous one in this case. 228 | if (position.second < token.Line) 229 | return getPrevious(root); 230 | if (position.second == token.Line && position.first < token.Column) 231 | return getPrevious(root); 232 | 233 | int length = token.StopIndex - token.StartIndex + 1; 234 | if (position.second == token.Line && (position.first < token.Column + length)) 235 | return root; 236 | } 237 | } while (root != null); 238 | 239 | return null; 240 | } 241 | 242 | public static bool treeContainsPosition(IParseTree node, int position) 243 | { 244 | var terminal = node as ITerminalNode; 245 | if (terminal != null) 246 | { 247 | return terminal.Symbol.StartIndex <= position && position <= terminal.Symbol.StopIndex; 248 | } 249 | 250 | var context = node as ParserRuleContext; 251 | if (context == null) 252 | return false; 253 | 254 | return context.Start.StartIndex <= position && position <= context.Stop.StopIndex; 255 | } 256 | 257 | public IParseTree contextFromPosition(IParseTree root, int position) 258 | { 259 | if (!treeContainsPosition(root, position)) 260 | return null; 261 | for (int childIndex = 0; childIndex < root.ChildCount; childIndex++) 262 | { 263 | var child = root.GetChild(childIndex); 264 | var result = contextFromPosition(child, position); 265 | if (result != null) 266 | return result; 267 | } 268 | 269 | // No child contains the given position, so it must be in whitespaces between them. Return the root for that case. 270 | return root; 271 | } 272 | 273 | //public SymbolTable parsers::functionSymbolsForVersion(mySqlVersion version) 274 | //{ 275 | // static std::map functionSymbols; 276 | 277 | // if (functionSymbols.count(version) == 0) 278 | // { 279 | // auto & functions = mySqlSymbolInfo::systemFunctionsForVersion(version); 280 | // SymbolTable & symbolTable = functionSymbols[version]; // Creates the new symbol table. 281 | 282 | // for (auto function : functions) 283 | // { 284 | // symbolTable.addNewSymbol(nullptr, function, nullptr); 285 | // } 286 | // } 287 | // return &functionSymbols[version]; 288 | //} 289 | 290 | } 291 | -------------------------------------------------------------------------------- /CodeParser/Parser/MySql/MySqlServerVersion.cs: -------------------------------------------------------------------------------- 1 | public static class MySqlServerVersion 2 | { 3 | public const int MIN_SERVER_VERSION = 50600; 4 | public const int MAX_SERVER_VERSION = 99999; 5 | } -------------------------------------------------------------------------------- /CodeParser/Parser/ParserDispatchingErrorListener.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using System.IO; 3 | 4 | class ParserDispatchingErrorListener : IAntlrErrorListener 5 | { 6 | Parser _parent; 7 | 8 | public ParserDispatchingErrorListener(Parser parent) 9 | { 10 | _parent = parent; 11 | } 12 | public void SyntaxError(TextWriter output, IRecognizer recognizer, IToken offendingSymbol, int line, int charPositionInLine, string msg, RecognitionException e) 13 | { 14 | var foo = new ProxyErrorListener(_parent.ErrorListeners); 15 | foo.SyntaxError(output, recognizer, offendingSymbol, line, charPositionInLine, msg, e); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /CodeParser/Parser/Php/PhpLexerBase.cs: -------------------------------------------------------------------------------- 1 | /* 2 | PHP grammar. 3 | The MIT License (MIT). 4 | Copyright (c) 2015-2017, Ivan Kochurkin (kvanttt@gmail.com), Positive Technologies. 5 | Copyright (c) 2019, Thierry Marianne (thierry.marianne@weaving-the-web.org) 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | THE SOFTWARE. 24 | */ 25 | 26 | using System; 27 | using System.IO; 28 | using System.Reflection; 29 | using Antlr4.Runtime; 30 | using Antlr4.Runtime.Misc; 31 | 32 | public abstract class PhpLexerBase : Lexer 33 | { 34 | protected bool AspTags = true; 35 | protected bool _scriptTag; 36 | protected bool _styleTag; 37 | protected string _heredocIdentifier; 38 | protected int _prevTokenType; 39 | protected string _htmlNameText; 40 | protected bool _phpScript; 41 | protected bool _insideString; 42 | 43 | protected PhpLexerBase(ICharStream input) 44 | : base(input) 45 | { 46 | } 47 | 48 | protected PhpLexerBase(ICharStream input, TextWriter output, TextWriter errorOutput) 49 | : base(input, output, errorOutput) 50 | { 51 | } 52 | 53 | public override IToken NextToken() 54 | { 55 | CommonToken token = (CommonToken)base.NextToken(); 56 | 57 | if (token.Type == PhpLexer.PHPEnd || token.Type == PhpLexer.PHPEndSingleLineComment) 58 | { 59 | if (CurrentMode == PhpLexer.SingleLineCommentMode) 60 | { 61 | // SingleLineCommentMode for such allowed syntax: 62 | // 63 | PopMode(); // exit from SingleLineComment mode. 64 | } 65 | PopMode(); // exit from PHP mode. 66 | 67 | if (string.Equals(token.Text, "", System.StringComparison.Ordinal)) 68 | { 69 | _phpScript = false; 70 | token.Type = PhpLexer.HtmlScriptClose; 71 | } 72 | else 73 | { 74 | // Add semicolon to the end of statement if it is absente. 75 | // For example: 76 | if (_prevTokenType == PhpLexer.SemiColon || _prevTokenType == PhpLexer.Colon 77 | || _prevTokenType == PhpLexer.OpenCurlyBracket || _prevTokenType == PhpLexer.CloseCurlyBracket) 78 | { 79 | token.Channel = PhpLexer.SkipChannel; 80 | } 81 | else 82 | { 83 | token.Type = PhpLexer.SemiColon; 84 | } 85 | } 86 | } 87 | else if (token.Type == PhpLexer.HtmlName) 88 | { 89 | _htmlNameText = token.Text; 90 | } 91 | else if (token.Type == PhpLexer.HtmlDoubleQuoteString) 92 | { 93 | if (string.Equals(token.Text, "php", System.StringComparison.OrdinalIgnoreCase) && 94 | string.Equals(_htmlNameText, "language")) 95 | { 96 | _phpScript = true; 97 | } 98 | } 99 | else if (CurrentMode == PhpLexer.HereDoc) 100 | { 101 | // Heredoc and Nowdoc syntax support: http://php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc 102 | switch (token.Type) 103 | { 104 | case PhpLexer.StartHereDoc: 105 | case PhpLexer.StartNowDoc: 106 | _heredocIdentifier = token.Text.Substring(3).Trim().Trim('\''); 107 | break; 108 | 109 | case PhpLexer.HereDocText: 110 | if (CheckHeredocEnd(token.Text)) 111 | { 112 | PopMode(); 113 | 114 | var heredocIdentifier = GetHeredocIdentifier(token.Text); 115 | if (token.Text.Trim().EndsWith(";")) 116 | { 117 | token.Text = heredocIdentifier + ";\n"; 118 | token.Type = PhpLexer.SemiColon; 119 | } 120 | else 121 | { 122 | token = (CommonToken)base.NextToken(); 123 | token.Text = heredocIdentifier + "\n;"; 124 | } 125 | } 126 | break; 127 | } 128 | } 129 | else if (CurrentMode == PhpLexer.PHP) 130 | { 131 | if (Channel != Hidden) 132 | { 133 | _prevTokenType = token.Type; 134 | } 135 | } 136 | 137 | return token; 138 | } 139 | 140 | protected string GetHeredocIdentifier(string text) 141 | { 142 | text = text.Trim(); 143 | bool semi = text.Length > 0 ? text[text.Length - 1] == ';' : false; 144 | return semi ? text.Substring(0, text.Length - 1) : text; 145 | } 146 | 147 | protected bool CheckHeredocEnd(string text) 148 | { 149 | return string.Equals(GetHeredocIdentifier(text), _heredocIdentifier, System.StringComparison.Ordinal); 150 | } 151 | 152 | protected bool IsNewLineOrStart(int pos) 153 | { 154 | return InputStream.LA(pos) <= 0 || InputStream.LA(pos) == '\r' || InputStream.LA(pos) == '\n'; 155 | } 156 | 157 | protected void PushModeOnHtmlClose() 158 | { 159 | PopMode(); 160 | if (_scriptTag) 161 | { 162 | if (!_phpScript) 163 | { 164 | PushMode(PhpLexer.SCRIPT); 165 | } 166 | else 167 | { 168 | PushMode(PhpLexer.PHP); 169 | } 170 | _scriptTag = false; 171 | } 172 | else if (_styleTag) 173 | { 174 | PushMode(PhpLexer.STYLE); 175 | _styleTag = false; 176 | } 177 | } 178 | 179 | protected bool HasAspTags() 180 | { 181 | return AspTags; 182 | } 183 | 184 | protected bool HasPhpScriptTag() 185 | { 186 | return _phpScript; 187 | } 188 | 189 | protected void PopModeOnCurlyBracketClose() 190 | { 191 | if (_insideString) 192 | { 193 | _insideString = false; 194 | Channel = PhpLexer.SkipChannel; 195 | PopMode(); 196 | } 197 | } 198 | 199 | protected bool ShouldPushHereDocMode(int pos) 200 | { 201 | return InputStream.LA(pos) == '\r' || InputStream.LA(pos) == '\n'; 202 | } 203 | 204 | protected bool IsCurlyDollar(int pos) { 205 | return InputStream.LA(pos) == '$'; 206 | } 207 | 208 | protected void SetInsideString() { 209 | _insideString = true; 210 | } 211 | } -------------------------------------------------------------------------------- /CodeParser/Parser/PlSql/PlSqlLexerBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Reflection; 4 | using Antlr4.Runtime; 5 | using Antlr4.Runtime.Misc; 6 | using Antlr4.Runtime; 7 | 8 | public class PlSqlLexerBase : Lexer 9 | { 10 | ICharStream myinput; 11 | public PlSqlLexerBase self; 12 | 13 | public override string[] RuleNames => throw new NotImplementedException(); 14 | 15 | public override IVocabulary Vocabulary => throw new NotImplementedException(); 16 | 17 | public override string GrammarFileName => throw new NotImplementedException(); 18 | 19 | protected PlSqlLexerBase(ICharStream input, TextWriter output, TextWriter errorOutput) 20 | : base(input, output, errorOutput) 21 | { 22 | myinput = input; 23 | self = this; 24 | } 25 | 26 | public PlSqlLexerBase(ICharStream input) 27 | : base(input) 28 | { 29 | myinput = input; 30 | self = this; 31 | } 32 | 33 | public bool IsNewlineAtPos(int pos) 34 | { 35 | int la = myinput.LA(pos); 36 | return la == -1 || la == '\n'; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /CodeParser/Parser/PlSql/PlSqlParserBase.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using System; 3 | using System.IO; 4 | using System.Reflection; 5 | using Antlr4.Runtime; 6 | using Antlr4.Runtime.Misc; 7 | using Antlr4.Runtime; 8 | 9 | public abstract class PlSqlParserBase : Parser 10 | { 11 | private bool _isVersion10 = false; 12 | private bool _isVersion12 = true; 13 | public PlSqlParserBase self; 14 | 15 | protected PlSqlParserBase(ITokenStream input) 16 | : base(input) 17 | { 18 | self = this; 19 | } 20 | 21 | public PlSqlParserBase(ITokenStream input, TextWriter output, TextWriter errorOutput) : this(input) 22 | { 23 | } 24 | 25 | public bool isVersion10() => _isVersion10; 26 | 27 | public bool isVersion12() => _isVersion12; 28 | 29 | public bool setVersion10(bool value) => _isVersion10 = value; 30 | 31 | public bool setVersion12(bool value) => _isVersion12 = value; 32 | } 33 | -------------------------------------------------------------------------------- /CodeParser/Parser/PostgreSql/PostgreSqlLexerBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Antlr4.Runtime; 3 | using System.Collections.Generic; 4 | using System.Diagnostics; 5 | using System.IO; 6 | 7 | public class PostgreSqlLexerBase : Lexer 8 | { 9 | protected static Queue tags = new Queue(); 10 | 11 | public PostgreSqlLexerBase(ICharStream input) : base(input) 12 | { 13 | } 14 | public PostgreSqlLexerBase(ICharStream input, TextWriter output, TextWriter errorOutput) 15 | : base(input, output, errorOutput) 16 | { 17 | } 18 | 19 | private IIntStream getInputStream() { return InputStream; } 20 | public override string[] RuleNames => throw new NotImplementedException(); 21 | 22 | public override IVocabulary Vocabulary => throw new NotImplementedException(); 23 | 24 | public override string GrammarFileName => throw new NotImplementedException(); 25 | 26 | public void pushTag() { tags.Enqueue(this.Text); } 27 | 28 | public bool isTag() { return this.Text.Equals(tags.Peek()); } 29 | 30 | public void popTag() 31 | { 32 | tags.Dequeue(); 33 | } 34 | 35 | public void UnterminatedBlockCommentDebugAssert() 36 | { 37 | Debug.Assert(InputStream.LA(1) == -1 /*EOF*/); 38 | } 39 | 40 | public bool checkLA(int c) 41 | { 42 | return getInputStream().LA(1) != c; 43 | } 44 | 45 | public bool charIsLetter() 46 | { 47 | return Char.IsLetter((char)InputStream.LA(-1)); 48 | } 49 | 50 | public void HandleNumericFail() 51 | { 52 | InputStream.Seek(getInputStream().Index - 2); 53 | Type = PostgreSqlLexer.Integral; 54 | } 55 | 56 | public void HandleLessLessGreaterGreater() 57 | { 58 | if (Text == "<<") Type = PostgreSqlLexer.LESS_LESS; 59 | if (Text == ">>") Type = PostgreSqlLexer.GREATER_GREATER; 60 | } 61 | 62 | public bool CheckIfUtf32Letter() 63 | { 64 | return Char.IsLetter(Char.ConvertFromUtf32(Char.ConvertToUtf32((char)InputStream.LA(-2), (char)InputStream.LA(-1))).Substring(0)[0]); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /CodeParser/Parser/PostgreSql/PostgreSqlParserBase.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using Antlr4.Runtime.Tree; 3 | using Antlr4.Runtime.Atn; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | 8 | public abstract class PostgreSqlParserBase : Parser 9 | { 10 | public PostgreSqlParserBase(ITokenStream input) : base(input) 11 | { 12 | } 13 | 14 | public PostgreSqlParserBase(ITokenStream input, TextWriter output, TextWriter errorOutput) : base(input, output, errorOutput) 15 | { 16 | } 17 | 18 | internal IParseTree GetParsedSqlTree(string script, int line = 0) 19 | { 20 | var ph = getPostgreSqlParser(script); 21 | var result = ph.root(); 22 | return result; 23 | } 24 | 25 | internal void ParseRoutineBody(PostgreSqlParser.Createfunc_opt_listContext _localctx) 26 | { 27 | var lang = 28 | _localctx 29 | .createfunc_opt_item() 30 | .FirstOrDefault(coi => coi.LANGUAGE() != null) 31 | ?.nonreservedword_or_sconst()?.nonreservedword()?.identifier()? 32 | .Identifier()?.GetText(); 33 | var func_as = _localctx.createfunc_opt_item() 34 | .FirstOrDefault(coi => coi.func_as() != null); 35 | if (func_as != null) 36 | { 37 | var txt = GetRoutineBodyString(func_as.func_as().sconst(0)); 38 | var line = func_as.func_as() 39 | .sconst(0).Start.Line; 40 | var ph = getPostgreSqlParser(txt); 41 | switch (lang) 42 | { 43 | case "plpgsql": 44 | func_as.func_as().Definition = ph.plsqlroot(); 45 | break; 46 | case "sql": 47 | func_as.func_as().Definition = ph.root(); 48 | break; 49 | } 50 | } 51 | } 52 | 53 | private string TrimQuotes(string s) 54 | { 55 | return string.IsNullOrEmpty(s) ? s : s.Substring(1, s.Length - 2); 56 | } 57 | 58 | public string unquote(string s) 59 | { 60 | var r = new StringBuilder(s.Length); 61 | var i = 0; 62 | while (i < s.Length) 63 | { 64 | var c = s[i]; 65 | r.Append(c); 66 | if (c == '\'' && i < s.Length - 1 && (s[i + 1] == '\'')) i++; 67 | i++; 68 | } 69 | return r.ToString(); 70 | } 71 | 72 | public string GetRoutineBodyString(PostgreSqlParser.SconstContext rule) 73 | { 74 | var anysconst = rule.anysconst(); 75 | var StringConstant = anysconst.StringConstant(); 76 | if (null != StringConstant) return unquote(TrimQuotes(StringConstant.GetText())); 77 | var UnicodeEscapeStringConstant = anysconst.UnicodeEscapeStringConstant(); 78 | if (null != UnicodeEscapeStringConstant) return TrimQuotes(UnicodeEscapeStringConstant.GetText()); 79 | var EscapeStringConstant = anysconst.EscapeStringConstant(); 80 | if (null != EscapeStringConstant) return TrimQuotes(EscapeStringConstant.GetText()); 81 | string result = ""; 82 | var dollartext = anysconst.DollarText(); 83 | foreach (var s in dollartext) 84 | { 85 | result += s; 86 | } 87 | return result; 88 | } 89 | 90 | public PostgreSqlParser getPostgreSqlParser(string script) 91 | { 92 | var charStream = CharStreams.fromString(script); 93 | var lexer = new PostgreSqlLexer(charStream); 94 | var tokens = new CommonTokenStream(lexer); 95 | var parser = new PostgreSqlParser(tokens); 96 | lexer.RemoveErrorListeners(); 97 | parser.RemoveErrorListeners(); 98 | var listener_lexer = new LexerDispatchingErrorListener((this.InputStream as CommonTokenStream).TokenSource as Lexer); 99 | var listener_parser = new ParserDispatchingErrorListener(this); 100 | lexer.AddErrorListener(listener_lexer); 101 | parser.AddErrorListener(listener_parser); 102 | return parser; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /CodeParser/Parser/Python/Python3LexerBase.cs: -------------------------------------------------------------------------------- 1 | using Antlr4.Runtime; 2 | using System.Collections.Generic; 3 | using System; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text.RegularExpressions; 7 | 8 | public abstract class Python3LexerBase : Lexer { 9 | // A queue where extra tokens are pushed on (see the NEWLINE lexer rule). 10 | private LinkedList Tokens = new LinkedList(); 11 | // The stack that keeps track of the indentation level. 12 | private Stack Indents = new Stack(); 13 | // The amount of opened braces, brackets and parenthesis. 14 | private int Opened = 0; 15 | // The most recently produced token. 16 | private IToken LastToken = null; 17 | 18 | public Python3LexerBase(ICharStream input) 19 | : base(input) 20 | { 21 | } 22 | public Python3LexerBase(ICharStream input, TextWriter output, TextWriter errorOutput) 23 | : base(input, output, errorOutput) 24 | { 25 | } 26 | 27 | public override void Emit(IToken token) 28 | { 29 | base.Token = token; 30 | Tokens.AddLast(token); 31 | } 32 | 33 | private CommonToken CommonToken(int type, string text) 34 | { 35 | int stop = CharIndex - 1; 36 | int start = text.Length == 0 ? stop : stop - text.Length + 1; 37 | return new CommonToken(Tuple.Create((ITokenSource)this, (ICharStream)InputStream), type, DefaultTokenChannel, start, stop); 38 | } 39 | 40 | private IToken CreateDedent() 41 | { 42 | var dedent = CommonToken(Python3Parser.DEDENT, ""); 43 | dedent.Line = LastToken.Line; 44 | return dedent; 45 | } 46 | 47 | public override IToken NextToken() 48 | { 49 | // Check if the end-of-file is ahead and there are still some DEDENTS expected. 50 | if (((ICharStream)InputStream).LA(1) == Eof && Indents.Count != 0) 51 | { 52 | // Remove any trailing EOF tokens from our buffer. 53 | for (var node = Tokens.First; node != null; ) 54 | { 55 | var temp = node.Next; 56 | if (node.Value.Type == Eof) 57 | { 58 | Tokens.Remove(node); 59 | } 60 | node = temp; 61 | } 62 | 63 | // First emit an extra line break that serves as the end of the statement. 64 | this.Emit(CommonToken(Python3Parser.NEWLINE, "\n")); 65 | 66 | // Now emit as much DEDENT tokens as needed. 67 | while (Indents.Count != 0) 68 | { 69 | Emit(CreateDedent()); 70 | Indents.Pop(); 71 | } 72 | 73 | // Put the EOF back on the token stream. 74 | Emit(CommonToken(Python3Parser.Eof, "")); 75 | } 76 | 77 | var next = base.NextToken(); 78 | if (next.Channel == DefaultTokenChannel) 79 | { 80 | // Keep track of the last token on the default channel. 81 | LastToken = next; 82 | } 83 | 84 | if (Tokens.Count == 0) 85 | { 86 | return next; 87 | } 88 | else 89 | { 90 | var x = Tokens.First.Value; 91 | Tokens.RemoveFirst(); 92 | return x; 93 | } 94 | } 95 | 96 | // Calculates the indentation of the provided spaces, taking the 97 | // following rules into account: 98 | // 99 | // "Tabs are replaced (from left to right) by one to eight spaces 100 | // such that the total number of characters up to and including 101 | // the replacement is a multiple of eight [...]" 102 | // 103 | // -- https://docs.python.org/3.1/reference/lexical_analysis.html#indentation 104 | static int GetIndentationCount(string spaces) 105 | { 106 | int count = 0; 107 | foreach (char ch in spaces.ToCharArray()) 108 | { 109 | count += ch == '\t' ? 8 - (count % 8) : 1; 110 | } 111 | return count; 112 | } 113 | 114 | public bool atStartOfInput() 115 | { 116 | return Column == 0 && Line == 1; 117 | } 118 | 119 | public void openBrace(){ 120 | Opened++; 121 | } 122 | 123 | public void closeBrace(){ 124 | Opened--; 125 | } 126 | 127 | public void onNewLine(){ 128 | var newLine = (new Regex("[^\r\n\f]+")).Replace(Text, ""); 129 | var spaces = (new Regex("[\r\n\f]+")).Replace(Text, ""); 130 | 131 | // Strip newlines inside open clauses except if we are near EOF. We keep NEWLINEs near EOF to 132 | // satisfy the final newline needed by the single_put rule used by the REPL. 133 | int next = ((ICharStream)InputStream).LA(1); 134 | int nextnext = ((ICharStream)InputStream).LA(2); 135 | if (Opened > 0 || (nextnext != -1 && (next == '\r' || next == '\n' || next == '\f' || next == '#'))) 136 | { 137 | // If we're inside a list or on a blank line, ignore all indents, 138 | // dedents and line breaks. 139 | Skip(); 140 | } 141 | else 142 | { 143 | Emit(CommonToken(Python3Lexer.NEWLINE, newLine)); 144 | int indent = GetIndentationCount(spaces); 145 | int previous = Indents.Count == 0 ? 0 : Indents.Peek(); 146 | if (indent == previous) 147 | { 148 | // skip indents of the same size as the present indent-size 149 | Skip(); 150 | } 151 | else if (indent > previous) { 152 | Indents.Push(indent); 153 | Emit(CommonToken(Python3Parser.INDENT, spaces)); 154 | } 155 | else { 156 | // Possibly emit more than 1 DEDENT token. 157 | while(Indents.Count != 0 && Indents.Peek() > indent) 158 | { 159 | this.Emit(CreateDedent()); 160 | Indents.Pop(); 161 | } 162 | } 163 | } 164 | } 165 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CodeParser 2 | Parse code using antlr. 3 | 4 | * The lexer and parser classes in **CodeParser** are generated by [Antlr grammar file](https://github.com/antlr/grammars-v4). 5 | * The **CodeParser.Test** demonstrates how to parse source code file to extract class and interface with their properties and methods. 6 | * The **CodeParser.Viewer** is a visual tool to analyse the parser rules. 7 | 8 | ## Example 9 | 10 | *Python* 11 | * source code 12 | ~~~ 13 | #!/usr/bin/python3 14 | 15 | class HelloWorld(): 16 | owner = "" 17 | target = "" 18 | def sayHello(self, word): 19 | print(word) 20 | 21 | x = HelloWorld() 22 | 23 | x.sayHello("Hello") 24 | ~~~ 25 | 26 | * parser test output 27 | ~~~ 28 | Class:HelloWorld 29 | { 30 | Field:owner 31 | Field:target 32 | Method:sayHello 33 | } 34 | ~~~ 35 | ## Viewer 36 | ![CodePaser Viewer](https://github.com/victor-wiki/StaticResources/blob/master/StaticResources/images/projs/CodeParser/Viewer.png?raw=true&rid=1) 37 | 38 | ![CodePaser Viewer](https://github.com/victor-wiki/StaticResources/blob/master/StaticResources/images/projs/CodeParser/Viewer2.png?raw=true&rid=1) 39 | 40 | ## Use Case 41 | The library [SqlAnalyser.Core](https://github.com/victor-wiki/DatabaseManager/tree/master/DatabaseConverter/SqlAnalyser.Core) of [DatabaseManager](https://github.com/victor-wiki/DatabaseManager) project uses the TSqlParser, MySqlParser, PlSqlParser and PostgreSqlParser to parse and translate view, function, procedure and table trigger between SqlServer, MySql, Oracle and Postgres. 42 | --------------------------------------------------------------------------------