我正在尝试使用Antlr4为SQL语句构建一个解析器。我并不关心我使用哪种特定的SQL语法,因为我计划强制执行只允许ANSI SQL,但在下面的示例中,我恰好对the使用了语法。以下是我的简单代码:
String sql = "SELECT ROW_NUMBER() OVER (ORDER BY id) FROM some_table";
TSqlLexer tSqlLexer = new TSqlLexer(CharStreams.fromString(sql));
CommonTokenStream stream = new CommonTokenStream(tSqlLexer);
TSqlParser parser = new TSqlParser(stream);
ParseTree tree = parser.tsql_file(); // errors happen here
ParseTreeWalker walker = new ParseTreeWalker();
// I built a custom listener, so far not much in it
AnalyticFunctionBaseListener listener = new AnalyticFunctionBaseListener();
walker.walk(listener, tree);在生成以下错误/警告之前,代码只得到对tsql_file()的调用:
line 1:35 token recognition error at: 'i'
line 1:36 token recognition error at: 'd'
line 1:44 token recognition error at: 's'
line 1:45 token recognition error at: 'o'
line 1:46 token recognition error at: 'm'
line 1:47 token recognition error at: 'e'
line 1:49 token recognition error at: 't'
line 1:50 token recognition error at: 'a'
line 1:51 token recognition error at: 'b'
line 1:52 token recognition error at: 'l'
line 1:53 token recognition error at: 'e'
line 1:37 no viable alternative at input 'SELECTROW_NUMBER()OVER(ORDERBY)'很明显,我在这里错过了一些重要的东西,但我不知道那是什么。我使用在ANTLR GitHub位点上可用的TSQL发布的语法进行构建。
任何Antlr古鲁能修改上面的片段以使其工作吗?我希望有人能给出一个典型的示例,说明如何使用Antlr来解析基本SQL语句。
发布于 2021-01-26 18:16:38
注意自述文件中的以下注释
用法、重要注意事项 由于SQL语法通常不区分大小写,但此语法实现是区分大小写的,因此必须使用自定义字符流将所有字符转换为大写字符,然后才能将它们发送到lexer。 您可以找到更多的信息这里与各种目标语言的实现。
简而言之,更改您的代码:
String sql = "SELECT ROW_NUMBER() OVER (ORDER BY id) FROM some_table";
TSqlLexer tSqlLexer = new TSqlLexer(CharStreams.fromString(sql));至:
String sql = "SELECT ROW_NUMBER() OVER (ORDER BY id) FROM some_table";
CharStream s = CharStreams.fromString(sql);
TSqlLexer tSqlLexer = new TSqlLexer(new CaseChangingCharStream(s, true));在这里查找CaseChangingCharStream的来源:https://github.com/antlr/antlr4/blob/master/doc/resources/CaseChangingCharStream.java
编辑
在评论中,Mike建议:
或者,您可以使用MySQL文法,它支持不区分大小写的关键字,而不需要额外的流。
这可能是个更好的选择。我并不是说MySQL语法不好/不准确,但麦克建议的语法来自于官方的MySQL回购(而迈克对此做出了贡献),这会让我对它的质量充满信心。
https://stackoverflow.com/questions/65904479
复制相似问题