使用 ANTLR 4 解析 SQL 'between' 和 'and' 表达式

Parsing SQL 'between' and 'and' expressions with ANTLR 4

我在使用 SQL 表达式解析器时遇到困难。具体来说,使用 a AND ba 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
...

作为 BetweenExpressionlower={0.02 - 0.01 AND 0.02 + 0.01}upper={l_quantity < 25}。显然,我希望将其解析为 lower={0.02 - 0.01}upper={0.02 + 0.01},并以 AndExpression 作为父节点。

基本上,我希望 BetweenExpressionlower=exprRule 取最少的令牌,而不是最多的令牌。在我看来,应该有一个直接的解决方案,但我缺乏术语来表达正确的 google 搜索,也无法在 ANTLR 文档中找到答案。

我也试过,按照 mnesarco 的建议,给 BETWEEN 表达式 alt 更高的优先级,但在这两种情况下,解析树:

已创建。想想也是有道理的。

我唯一能想到的是引入一个额外的 "numeric expression" 规则,它不匹配 andbetween 表达式:

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
 ;

这导致解析树:

看起来像是一个优先级问题。基本上你需要 [Between] 运算符的优先级高于 [And] 并且可能也高于 [Or]。

在 Antlr4 中,优先级只是定义的顺序。因此,只需尝试交换替代顺序。即:

| value=exprRule K_NOT? K_BETWEEN lower=exprRule K_AND upper=exprRule  # BetweenExpression
| lhs=exprRule K_AND rhs=exprRule  # AndExpression