ANTLR4解析SQL BETWEEN与AND歧义问题的解决问询
解决ANTLR4解析SQLite表达式的歧义问题
问题根源
你的语法未区分**BETWEEN结构中的AND与逻辑AND**的优先级,也没有对表达式进行层级划分。ANTLR4的左递归解析规则会优先把后续的AND绑定到BETWEEN的upper表达式上,导致将0 BETWEEN 0 AND 2 AND 1 <9错误解析为0 BETWEEN (0 AND 2) AND 1 <9,而非SQLite预期的(0 BETWEEN 0 AND 2) AND 1 <9。
SQLite中BETWEEN ... AND ...里的AND是语法关键字,属于BETWEEN表达式的一部分;而逻辑AND是更高层级的布尔运算符,优先级低于BETWEEN表达式,两者必须通过语法规则明确区分。
解决方案:通过语法分层划分优先级
将表达式按优先级从高到低拆分层级,确保BETWEEN表达式优先被解析为整体,再与其他表达式通过逻辑AND/OR连接。修改后的语法如下:
expression : or_expression #orExpr ; or_expression : and_expression #andExpr | or_expression OR and_expression #orOperation ; and_expression : between_expression #betweenExpr | and_expression AND between_expression #andOperation ; between_expression : comparison_expression #compExpr | value=comparison_expression NOT? BETWEEN lower=comparison_expression AND upper=comparison_expression #betweenOperation ; comparison_expression : term #termExpr | comparison_expression '<' comparison_expression #lessThanOperation // 可添加其他比较运算符:>, =, <=, >=, != 等 ; term : NUMBER #numberTerm ; // 词法规则 NUMBER : [0-9]+;
语法说明
- 优先级层级:从高到低依次为:数字(
term) → 比较表达式(如<) →BETWEEN表达式 → 逻辑AND→ 逻辑OR BETWEEN边界限制:BETWEEN的lower和upper仅接受comparison_expression级别的表达式,无法包含逻辑AND/OR,避免了将后续逻辑AND误解析为BETWEEN结构的一部分。- 逻辑运算符结合性:通过左递归规则(如
and_expression AND between_expression)确保逻辑AND/OR遵循左结合性,与SQLite的行为一致。
修改后,解析器会先将0 BETWEEN 0 AND 2解析为完整的between_expression,再将其与1 <9(comparison_expression→between_expression)通过逻辑AND连接,完全匹配SQLite的解析结果。
内容的提问来源于stack exchange,提问作者Travis Parks
相关产品推荐
相关产品推荐

