我在使用SQL表达式解析器时遇到困难。具体来说,使用a AND b
和a BETWEEN c AND d
规则。指定的替代方法如下:
| lhs=exprRule K_AND rhs=exprRule # AndExpression
| value=exprRule K_NOT? K_BETWEEN lower=exprRule K_AND upper=exprRule # BetweenExpression
不幸的是,该语法解析了一个字符串,例如
...
l_discount BETWEEN 0.02 - 0.01 AND 0.02 + 0.01
AND l_quantity < 25
...
为BetweenExpression
和lower={0.02 - 0.01 AND 0.02 + 0.01}
和upper={l_quantity < 25}
。显然,我希望将其解析为lower={0.02 - 0.01}
和upper={0.02 + 0.01}
,并以AndExpression
作为父节点。
基本上,我希望lower=exprRule
中的BetweenExpression
采用最少的令牌而不是最大的令牌。在我看来,应该对此有一个简单的解决方案,但是我缺乏用词表达正确的Google搜索的措辞,也无法在ANTLR文档中找到答案。
答案 0 :(得分:2)
正如mnesarco的建议,我还尝试给BETWEEN
表达式赋予更高的优先级,但是在两种情况下,都是解析树:
已创建。如果您考虑一下,那是有道理的。
我唯一能想到的就是引入一个额外的“数字表达式”规则,该规则与and
和between
表达式不匹配:
exprRule
: value=exprRule ( '+' | '-' ) lower=exprRule #AddExpression
| value=exprRule ( '<' | '>' | '<=' | '=>' ) lower=exprRule #ComparisonExpression
| value=exprRule K_NOT? K_BETWEEN lower=exprNumeric K_AND upper=exprNumeric #BetweenExpression
| lhs=exprRule K_AND rhs=exprRule #AndExpression
| NUMBER #NumberExpression
| ID #IdExpression
;
exprNumeric
: value=exprNumeric ( '+' | '-' ) lower=exprNumeric #AddNumericExpression
| NUMBER #NumNumericberExpression
| ID #IdNumericExpression
;
这将导致解析树:
答案 1 :(得分:-1)
它看起来像是一个优先问题。基本上,您需要[Between]运算符的优先级比[And]甚至还可能比[Or]高。
在Antlr4中,优先级只是定义的顺序。因此,只需尝试交换替代订单即可。即:
| value=exprRule K_NOT? K_BETWEEN lower=exprRule K_AND upper=exprRule # BetweenExpression
| lhs=exprRule K_AND rhs=exprRule # AndExpression