我在理解如何删除此语法中的左递归的在线解释时遇到问题。我知道如何删除直接递归,但我不清楚如何处理间接递归。有人可以解释一下吗?
appsettings.json
答案 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;编译器构造"很多年前的课程。我们不是编写解析器来适应特定的语法,而是转换语法以适应我们想要的解析器样式。