先决条件 – 上下文无关语法、歧义和解析器的分类
左递归:
形式的语法,
S --> S / a / b
它被称为左递归,其中 S 是任何非终结符,a 和 b 是任何终结符集。
左递归问题:
如果任何语法中存在左递归,那么在编译的语法分析部分的解析过程中,语法有可能会创建无限循环。这是因为每次产生语法 S 都会产生另一个 S 而不检查任何条件。
以示例删除左递归的算法:
假设我们有一个包含左递归的文法:
S-->S a / S b / c / d
- 检查给定的语法是否包含左递归,如果存在则分离产生式并开始处理它。
在我们的例子中,S-->S a/ S b /c / d
- 引入一个新的非终结符并将其写在每个终结符的最后。我们产生一个新的非终结符 S’ 并将新产生写为,
S-->cS' / dS'
- 在 LHS 中写入新产生的非终结符,在 RHS 中它可以产生或可以产生新的产生,其中跟在前一个 LHS 之后的终结符或非终结符最终将被新的非终结符替换。
S'-->? / aS' / bS'
所以转换后新的等效产量是
S-->cS' / dS' S'-->? / aS' / bS'
间接左递归:
如果从文法的任何符号开始,可以导出以该符号为头的字符串,则称该文法具有间接左递归。
例如,
A --> Br
B --> Cd
C --> At
其中 A、B、C 是非终结符,r、d、t 是终结符。
在这里,从 A 开始,我们可以通过将 C 替换为 B 和 B 替换为 A 再次推导出 A。
借助示例删除间接递归的算法:
A1 --> A2 A3
A2 --> A3 A1 / b
A3 --> A1 A1 / a
其中 A1、A2、A3 为非终端,a、b 为终端。
- 识别可能导致间接左递归的产生式。在我们的例子中,
A3--> A1 A1 / a
- 在终端所在的位置替代其生产在任何其他生产替代 A1-> A2 A3 的生产 A3 中。 A3 –> A2 A3 A1。
现在在这个生产中替换 A2–> A3 A1 / b 然后将其替换为,A3 --> A3 A1 A3 A1 / b A3 A1
- 现在新产生式转化为直接左递归的形式,用直接左递归的方法解决这个问题。
消除上面的直接左递归,A3 --> a | b A3 A1 | aA' | b A3 A1A' A' --> A1 A3 A1 | A1 A3 A1A'
产生的语法是:
A1 --> A2 A3 A2 --> A3 A1 | b A3 --> a | b A3 A1 | aA' | b A3 A1A' A' --> A1 A3 A1 | A1 A3 A1A'