我正在使用https://github.com/antlr/grammars-v4中的语法并尝试填充where子句中的列名和值。我遇到的问题是如何确定SQLiteParser.Column_nameContext和值上下文是否属于哪里。当有"和#34;它变得更加复杂。参与。
所以我想要的是"" /" b" (栏目)和" g" /" h" (值)在sql下面:
从表中选择*,其中a =" g"和b =" h&#34 ;;
答案 0 :(得分:1)
您似乎对expr
制作感兴趣。在这种情况下,您可以将基本侦听器附加到解析树并覆盖其enterExpr
方法:
String sql = "select * from table where a = \"g\" and b = \"h\"";
SQLiteLexer lexer = new SQLiteLexer(new ANTLRInputStream(sql));
SQLiteParser parser = new SQLiteParser(new CommonTokenStream(lexer));
ParseTree tree = parser.select_stmt();
ParseTreeWalker.DEFAULT.walk(new SQLiteBaseListener(){
@Override
public void enterExpr(@NotNull SQLiteParser.ExprContext ctx) {
if (ctx.children.size() == 3 && (ctx.children.get(1) instanceof TerminalNode)) {
String leftHandSide = ctx.children.get(0).getText();
String operator = ctx.children.get(1).getText();
String rightHandSide = ctx.children.get(2).getText();
System.out.printf("leftHandSide=%s, operator=%s, leftHandSide=%s\n",
leftHandSide, operator, rightHandSide);
}
}
}, tree);
将打印以下内容:
leftHandSide=a="g", operator=and, leftHandSide=b="h" leftHandSide=a, operator==, leftHandSide="g" leftHandSide=b, operator==, leftHandSide="h"
不是执行这样丑陋的(ctx.children.size() == 3 && (ctx.children.get(1) instanceof TerminalNode))
,而是通过在语法中添加标签来(大大)改进事物:
ANTLR 4 tree inject/rewrite operator
另请注意语法中的运算符优先级错误,请参阅以下pull请求:
https://github.com/antlr/grammars-v4/pull/47
具有固定运算符优先级的语法也可以在这里找到:
https://github.com/bkiers/sqlite-parser/blob/master/src/main/antlr4/nl/bigo/sqliteparser/SQLite.g4