1

假设我有一个格式的表达式

a>10 and b>20 and c>30

我想得到一个表达式列表如下

a>10
b>20
c>30

如果我使用表达式访问者模式,对于 AndExpression 访问者,我写了类似

public void visit(AndExpression andExpression) {
    andExpression.getLeftExpression().accept(this);
    andExpression.getRightExpression().accept(this);
}

但是,这会递归地运行并进入其他每个访问者模式方法。获得较小的表达式时如何停止?

如果我只使用 getLeftExpressions() 和 getRightExpression(),我在第一次运行中得到的是左边的“a>10”和右边的“b>20 和 c>30”。

4

2 回答 2

2

JSqlParser 以这种方式解析您的表达式:

AndExpression
   AndExpression
       a>10
       b>20
   c>30

我很想知道您使用哪个版本,如果递归确实在右侧而不是左侧。我使用JSqlParser 0.9-SNAPSHOT。尽管如此,在我的JSqlParser版本中(我认为,因为它是一个 LL 解析器),其他答案中的评论建议代码块

while(ex.getLeftExpression() != null) {
    list.add(ex.getLeftExpression()); 
    ex = ex.getRightExpression();
}

不管用。它发现(或收集):

a > 10 AND b > 20

这是一个AndExpression并且失败了ex = ex.getRightExpression();,因为权利永远不会是一个AndExpression。这就是 JSqlParser 的工作原理。递归将AndExpressionleftExpression.

所以这里有一个解决方案和一个小测试,使用JSqlParser V0.9-SNAPSHOT,它使用递归方式访问这些AndExpressions并打印出找到的表达式。我没有将它添加到List. 请原谅我。

public class JSqlParser1 {

    public static void main(String[] args) throws JSQLParserException {
        Expression expr = CCJSqlParserUtil.parseCondExpression("a>10 and b>20 and c>30");
        expr.accept(new ExpressionVisitorAdapter() {

            @Override
            public void visit(AndExpression expr) {
                if (expr.getLeftExpression() instanceof AndExpression) {
                    expr.getLeftExpression().accept(this);
                } else {
                    System.out.println(expr.getLeftExpression());
                }

                System.out.println(expr.getRightExpression());
            }

        });
    }
}

这个打印:

a > 10
b > 20
c > 30
于 2014-04-07T23:23:36.213 回答
1

在您的visit方法中,您可以返回Expression给定And表达式的列表。所以只需返回一个Expression对象列表,如下所示:

public List<Expression> visit(AndExpression andExpression) {
    List<Expression> list = new ArrayList<Expression>();
    lex = andExpression.getLeftExpression();
    list.add(lex);
    rex = andExpression.getRightExpression();
    subEx1 = rex.getLeftExpression();
    subEx2 = rex.getRightExpression();
    list.add(subEx1);
    list.add(subEx2);
    return list;
}

这两个子表达式是从第一个右表达式获得的。

于 2014-04-05T16:25:39.547 回答