消除间接左递归:因S→ε引发的递归处理咨询
处理由
S→ε引发的间接左递归:从转换到消除 嘿,这个问题我之前做文法分析的时候也踩过类似的坑,咱们一步步拆解搞定它:
第一步:把间接左递归转化为直接左递归
S→ε是触发间接左递归的关键,核心思路是把所有引用S的产生式里的S替换掉,把隐含的左递归暴露出来。具体操作步骤:
- 先找出所有右部包含
S的产生式(比如假设是X → γ S δ,其中γ、δ是任意文法符号串) - 对每个这样的产生式,拆分成两个分支:
- 一个保留原有的S:
X → γ S δ(对应S不取ε的情况) - 一个把S替换成ε:
X → γ δ(对应S取ε的情况)
- 一个保留原有的S:
- 再把S的非ε产生式(比如
S → α,α是不含ε的符号串)代入到保留S的那个产生式里,这时候就会出现直接左递归的结构。
举个具体例子更直观,假设你的文法是:
S → A | ε A → S a | b
代入后:
- 处理
A → S a:拆成A → A a(代入S→A)和A → a(代入S→ε) - 加上原来的
A → b,现在A的产生式变成了:A → A a | b | a——这就转化成了直接左递归。
第二步:消除直接左递归
得到直接左递归的结构后,就可以用标准的消除方法了:
对于形如A → A α | β₁ | β₂ | ... | βₙ的产生式(其中β₁~βₙ都不以A开头),我们可以重写成:
A → β₁ A' | β₂ A' | ... | βₙ A' A' → α A' | ε
拿上面的例子来说,α是a,β₁是b,β₂是a,改写后:
A → b A' | a A' A' → a A' | ε
再把S的产生式整合进去,最终消除左递归后的文法就是:
S → A | ε A → b A' | a A' A' → a A' | ε
额外提醒
如果你的文法里还有其他引用S的产生式,只需要重复第一步的代入操作就行——核心就是先通过ε产生式的替换,把间接左递归“摊开”成直接左递归,再用成熟的方法消除它。
内容的提问来源于stack exchange,提问作者nero
相关产品推荐
相关产品推荐

