消除间接左递归

时间:2017-09-06 23:01:24

标签: parsing recursion

我在理解如何删除此语法中的左递归的在线解释时遇到问题。我知道如何删除直接递归,但我不清楚如何处理间接递归。有人可以解释一下吗?

appsettings.json

1 个答案:

答案 0 :(得分:1)

我学会这样做的方法是用其每个扩展替换一个违规的非终端符号。在这种情况下,我们首先将 B 替换为其扩展:

A --> B x y | x
B --> C D

变为

A --> C x y | D x y | x

现在,我们对非终端符号 C

执行相同的操作
A --> C x y | D x y | x
C --> A | c

变为

A --> A x y | c x y | D x y | x

唯一剩下的其他语法规则是

D --> d

所以你也可以那个替换,把你的整个语法留作

A --> A x y | c x y | d x y | x

现在没有间接的左递归,因为根本没有间接的。

另见here

要完全消除左递归(不仅仅是间接左递归),请从您自己的材料中引入 A' 符号(为了这个澄清和完成,将信用额转移到OP) ):

A -> x A' 
A' -> xyA' | cxyA' | dxyA' | epsilon

回应 naomik 的评论

是的,语法具有有趣的属性,您可以根据语法规则的约束来表征某些语义功能。有一些转换算法可以处理某些类型的解析问题。

在这种情况下,我们想要删除左递归:语法的一个理想属性是使用任何规则必须消耗至少一个输入令牌(终端符号)。左递归为解析器中的无限递归打开了一扇门。

我在我的"计算基础"中学到了这些东西。和#34;编译器构造"很多年前的课程。我们不是编写解析器来适应特定的语法,而是转换语法以适应我们想要的解析器样式。