假设我有格式
的表达式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”。
答案 0 :(得分: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的工作原理。 AndExpression
递归将在leftExpression
。
所以这是一个解决方案,并使用 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
答案 1 :(得分: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;
}
这两个子表达式是从第一个右表达式中获得的。