问题描述
我有这个上下文无关语法,我正在尝试删除非终端 B 中的 lambda。如果没有它在 B 中递归地使用 lambda,我该如何处理?
S -> B
A -> λ | aAb
B -> BB | λ | C
C -> A | aCc
解决方法
在 λ 消元过程中,同一个产生式可能会被添加到一个产生式集合中两次或更多次。因为它是一个集合,所以它最多只能有一个元素,所以添加一个已经存在的元素没有任何作用。右手边是空的这一事实没有任何改变。
因此为了λ消除B
,我们需要找到B
的所有实例并添加新的产生式,并删除该使用。 B
的唯一用途是在 S
和 B
本身中,因此我们继续添加产生式:
- S → λ
- B → B(通过删除 B → B B 中的第一个 B);
- B → B(通过删除 B → B B 中的第二个 B);
- B → λ(通过从我们刚刚添加的产生式 B → B 中删除 B。)
然而,B 的任何新作品实际上都没有添加到集合中。递归单元产生式 (B → B) 被简单地丢弃,并且 B → λ 已经存在。
如果我们为起始符号以外的符号添加一个新的 λ 产生式,我们需要将该符号标记为需要 λ-消除(或递归调用消除过程)。但这不会发生在这里,因为添加的产品已经存在。
一旦我们完成了λ-消除,我们就移除所有 λ 产生式,除了开始符号。
在实践中,有一些可能的优化,但算法可能更清晰。