以一个(几乎)教科书示例为例,我们希望乘法优先于加法,但还包括一个匹配的可选部分。
expr : expr '*' expr ('ALSO')?
| expr '+' expr
| INT
;
INT: [0-9]+;
WS : [ \t\r\n]+ -> skip ;
使用3 * 4 + 2
尝试语法时,我们会得到一棵看起来像这样的意外树
expr:1
/ | \
expr:1 * expr:2
| / | \
3 expr:1 + expr:1
| |
4 2
但是,当使用3 + 4 * 2
时,我们会得到预期的结果
expr:1
/ | \
expr:1 + expr:2
| / | \
3 expr:1 * expr:1
| |
4 2
此外,如果您将可选令牌切换到第二行,我们每次都会获得预期的树。
expr : expr '*' expr
| expr '+' expr ('ALSO')?
| INT
;
我还使用非贪婪运算符??
并定义了词法分析器令牌来尝试此操作,因此我们不必担心由于隐式令牌而导致排序的奇异之处。
什么能解释这种顺序?
答案 0 :(得分:2)
那看起来像个错误。您可以在这里报告:https://github.com/antlr/antlr4/issues(如果尚未报告...我没有检查)
一种解决方法似乎是包括一个不包含ALSO
令牌的额外替代方案:
expr : expr '*' expr 'ALSO'
| expr '*' expr
| expr '+' expr
| INT
;
为3 * 4 + 2
和3 + 4 * 2
生成预期的解析树。