您似乎对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,运算符==,leftHandSide="g"
leftHandSide=b, operator==, leftHandSide="h"
您可以(极大地)通过在语法中添加标签来改进事情,而不是执行如此丑陋的(ctx.children.size() == 3 && (ctx.children.get(1) instanceof TerminalNode)):
ANTLR 4 tree inject/rewrite operator
还要注意语法中的运算符优先级是错误的,请看下面的拉取请求:
https://github.com/antlr/grammars-v4/pull/47
固定运算符优先级的语法也可以在这里找到:
https://github.com/bkiers/sqlite-parser/blob/master/src/main/antlr4/nl/bigo/sqliteparser/SQLite.g4