- Download and set up ANTLR4
- Download
PlSqlLexer.g4andPlSqlParser.g4from https://github.com/antlr/grammars-v4/tree/master/sql/plsql
-
Build the lexer (https://stackoverflow.com/a/55379369/1958726):
antlr4 PlSqlLexer.g4 -Dlanguage=CSharp -
Build the parser:
antlr4 PlSqlParser.g4 -Dlanguage=CSharp
-
PowerShell:
dotnet new console -n MyPlSqlProject cd .\MyPlSqlProject iwr https://github.com/antlr/grammars-v4/raw/master/sql/plsql/CSharp/PlSqlLexerBase.cs -OutFile PlSqlLexerBase.cs iwr https://github.com/antlr/grammars-v4/raw/master/sql/plsql/CSharp/PlSqlParserBase.cs -OutFile PlSqlParserBase.cs iwr https://raw.githubusercontent.com/antlr/antlr4/master/doc/resources/CaseChangingCharStream.cs -OutFile CaseChangingCharStream.cs -
Copy the
.csfiles that ANTLR generated in the previous section into the project folder. -
Fix namespaces; remove namespaces from
PlSqlLexerBase.csandPlSqlParserBase.cs, or addPlSqlParseTreeusings to their subclasses, or do something else (maybeantlr4takes a namespace argument when building the lexer and parser?). -
Add missing constructor overload to
PlSqlLexerBase.cs:public PlSqlLexerBase(ICharStream input, TextWriter output, TextWriter errorOutput) : base(input, output, errorOutput) { } -
Add missing constructor overload to
PlSqlParserBase.cs:protected PlSqlParserBase(ITokenStream input, TextWriter output, TextWriter errorOutput) : base(input, output, errorOutput) { } -
In
PlSqlLexerBase, changeint la = _input.La(pos);toint la = InputStream.LA(pos);if it hasn't been fixed in the repo yet. -
Insert into
Program.cs:var charStream = CharStreams.fromstring("My PL/SQL"); // or .fromPath or whatever var caseChangingCharStream = new CaseChangingCharStream(charStream, true); // Required for PL/SQL; see https://github.com/antlr/grammars-v4/blob/master/sql/plsql/README.md var lexer = new PlSqlLexer(caseChangingCharStream); var commonTokenStream = new CommonTokenStream(lexer); var parser = new PlSqlParser(commonTokenStream); -
For faster compilation, separate the ANTLR classes into their own class library project, and uncheck Build for it under Build > Configuration Manager.
If you just need to grab specific things, like all tableview names in a view DDL's from clause, you can use ANTLR's XPath class. Example:
var tableviews = XPath.FindAll(tree, "//create_view//from_clause//tableview_name", parser);
context.GetText() just returns the combined text of all child nodes; whitespace isn't included.
To get the full, original text, including whitespace, use:
caseChangingCharStream.GetText(new Interval(context.Start.StartIndex, context.Stop.StopIndex);
Sure, glad it helped!