如何使用左递归和贪婪的'选择解析器规则优先级?操作员?

时间:2019-03-27 20:45:33

标签: antlr4

以一个(几乎)教科书示例为例,我们希望乘法优先于加法,但还包括一个匹配的可选部分。

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
     ;

我还使用非贪婪运算符??并定义了词法分析器令牌来尝试此操作,因此我们不必担心由于隐式令牌而导致排序的奇异之处。

什么能解释这种顺序?

1 个答案:

答案 0 :(得分:2)

那看起来像个错误。您可以在这里报告:https://github.com/antlr/antlr4/issues(如果尚未报告...我没有检查)

一种解决方法似乎是包括一个不包含ALSO令牌的额外替代方案:

expr : expr '*' expr 'ALSO'
     | expr '*' expr
     | expr '+' expr
     | INT
     ;

3 * 4 + 23 + 4 * 2生成预期的解析树。

相关问题