如何从表达式中获取值

时间:2014-04-15 16:49:31

标签: antlr4

我正在使用https://github.com/antlr/grammars-v4中的语法并尝试填充where子句中的列名和值。我遇到的问题是如何确定SQLiteParser.Column_nameContext和值上下文是否属于哪里。当有"和#34;它变得更加复杂。参与。

所以我想要的是"" /" b" (栏目)和" g" /" h" (值)在sql下面:

从表中选择*,其中a =" g"和b =" h&#34 ;;

1 个答案:

答案 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