先决条件–上下文无关文法,歧义和解析器的分类
左递归:
形式的语法,
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
- 将其生产替换为A3生产中其他任何生产替代产品A1-> A2 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'