首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有关于如何使用Antlr 4解析SQL语句的典型示例吗?

有关于如何使用Antlr 4解析SQL语句的典型示例吗?
EN

Stack Overflow用户
提问于 2021-01-26 15:44:26
回答 1查看 1K关注 0票数 3

我正在尝试使用Antlr4为SQL语句构建一个解析器。我并不关心我使用哪种特定的SQL语法,因为我计划强制执行只允许ANSI SQL,但在下面的示例中,我恰好对the使用了语法。以下是我的简单代码:

代码语言:javascript
复制
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()的调用:

代码语言:javascript
复制
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语句。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-01-26 18:16:38

注意自述文件中的以下注释

用法、重要注意事项 由于SQL语法通常不区分大小写,但此语法实现是区分大小写的,因此必须使用自定义字符流将所有字符转换为大写字符,然后才能将它们发送到lexer。 您可以找到更多的信息这里与各种目标语言的实现。

简而言之,更改您的代码:

代码语言:javascript
复制
String sql = "SELECT ROW_NUMBER() OVER (ORDER BY id) FROM some_table";
TSqlLexer tSqlLexer = new TSqlLexer(CharStreams.fromString(sql));

至:

代码语言:javascript
复制
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回购(而迈克对此做出了贡献),这会让我对它的质量充满信心。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65904479

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档