Parsing 逐步消除这种间接的左递归

Parsing 逐步消除这种间接的左递归,parsing,context-free-grammar,left-recursion,Parsing,Context Free Grammar,Left Recursion,我已经看到一个应该能够用来删除所有左递归。 但我在这一特定语法方面遇到了问题: A -> Cd B -> Ce C -> A | B | f 无论我尝试什么,我都会以循环或仍然是间接左递归的语法结束 正确地实现这种语法的步骤是什么?已经解决了 我的困惑是,按照这个顺序,算法似乎什么都不做,所以我认为这一定是错误的,并开始在第一次迭代中替换->Cd(忽略j不能超过I)进入无限循环 1) 通过重新排列规则: C -> A | B | f A -> Cd B ->

我已经看到一个应该能够用来删除所有左递归。 但我在这一特定语法方面遇到了问题:

A -> Cd
B -> Ce
C -> A | B | f
无论我尝试什么,我都会以循环或仍然是间接左递归的语法结束


正确地实现这种语法的步骤是什么?

已经解决了

我的困惑是,按照这个顺序,算法似乎什么都不做,所以我认为这一定是错误的,并开始在第一次迭代中替换->Cd(忽略j不能超过I)进入无限循环

1) 通过重新排列规则:

C -> A | B | f 
A -> Cd
B -> Ce
2) 替换光盘中的C->Cd

C -> A | B | f 
A -> Ad | Bd | fd
B -> Ce
3) B还不在j的范围内,所以保留它并替换A的直接左递归

C -> A | B | f 
A -> BdA' | fdA'
A'-> dA' | epsylon
B -> Ce
4) 在B->Ce中替换C

C -> A | B | f 
A -> BdA' | fdA'
A'-> dA' | epsylon
B -> Ae | Be | fe
5) 还没做完!还需要替换新规则B->Ae(A的产量在j范围内)

6) 替换B的乘积中的直接左递归

C -> A | B | f 
A -> BdA' | fdA'
A'-> dA' | epsylon
B -> fdA'eB' | feB'
B'-> dA'eB' | eB' | epsylon

呜呼!左递归自由语法

规则是首先为非终端建立某种顺序,然后找到所有发生间接递归的路径

在这种情况下,顺序将是A
C=> A => Cd
C=> Cd | Ce | f

所以C的新规则是

C=> A => Cd
C=> Cd | Ce | f
现在您只需删除直接左递归即可:

C=> fC'
C'=> dC' | eC' | eps
由此产生的非递归语法是:

A => Cd
B => Ce
C => fC'
C' => dC' | eC' | eps

难道你不能简单地用eps | dD | eDhah,是的,你是对的!尽管以上是算法的良好实践,但这确实是最简单的重写。非常感谢。你有没有什么一般性的规则,或者仅仅是来自实践的常识第五步,B的第一个产品中有打字错误。应该是BdA。这应该迁移到cstheory.stackexchange.com,因为这与编程无关,只与CS理论有关。