2016-09-30 58 views
2

我有一个expression这是我的其他顶级事物的集合。在expression我有mathexpression (op) expression。有了这个,我得到什么时候/为什么相互左递归在Antlr中发生?

规则的以下几组相互左递归[表达,数学]

compileUnit : expression EOF; 

expression 
    : parens                
    | operation               
    | math 
    | variable               
    | number                
    | comparisonGroup             
    ; 

math : expression op=(ADD | SUBSTRACT | MULTIPLY | DIVIDE) expression  #mathExpression; 

无论其!

这是不是一个problem-

expression 
    : parens                
    | operation               
    | expression op=(ADD | SUBSTRACT | MULTIPLY | DIVIDE) expression 
    | variable               
    | number                
    | comparisonGroup             
    ; 

而且这也不是 - !

math : op=(ADD | SUBSTRACT | MULTIPLY | DIVIDE) expression expression  #mathExpression; 

那么,为什么我的第一个代码块的行为比其他两个例子不同?

回答

3

Antlr4可以处理直接左递归,但不是间接的左递归,其中左递归规则被定义为“直接或间接地在替代的左边缘上自我调用”的规则(TDAR;第71页)。

当,如在第一示例中,#mathExpression替代被分解出来的expression规则的和到一个单独的math规则,左直接递归变成间接,,规则“相互离开递归”。

正如在第二和第三个例子中所实现的,一个典型的解决方案是简单地将间接左递归规则组合到单个规则中。

+0

第一个例子没有显示直接左递归 - 这也会是一个问题吗?我没有TDAR,但我可能必须得到它。 –

+0

Antlr4可以处理直递左递归,其中递归“在左边调用*本身*”。数学规则创建了一个间接的左递归,因为它在左边引用了* another *规则。强烈推荐TDAR。 – GRosenberg

+0

刚刚看过https://youtu.be/q8p1voEiu8Q?t=38m32s。现在,我确定“这就是它”。希望在阅读TDAR之后,我将更好地理解*如何*一切正常,而不仅仅是*一切正常。 谢谢。 –