概念和使用
为了准确识别句柄,因此需要向前擦好看k个输入符号的LR分析。
LR(0)分析法
LR(0)项目
增广文法
引入这个新的开始产生式的目的是使得文法开始符号仅出现在一个产生式的左边,从而使得分析器只有一个接受状态。
当一个项目圆点后面是一个非终结符的时候,是存在等价项目的。
把等价的项目组成一个项目集合,成为项目集闭包,每个项目集闭包对应自动机的一个状态。
LR(0)自动机
下图中,每个方框内的项目都是等价的。
当得到的一组项目都是归约项目时,这时说明流程结束,可以根据自动机转换得到分析表。
在分析表中,如果某个状态是归约状态,则根据对应的产生式做出归约动作。
LR(0)分析表的问题
移进/归约冲突
从转换好的分析表中可以直接看出冲突
归约/归约冲突
如果LR(0)分析表中没有语法分析动作冲突,那么给定的文法则称为是LR(0)文法。
定义回顾:
CFG:上下文无关文法
消解冲突:可以通过SLR分析法、LR(1)分析法解决这类冲突问题。
SLR分析法
基本思想
本质上,其实就是LR(0)分析法的延申,对于归约动作做出了相关的约束。下面是SLR分析法的基本思想,但也是十分的难懂,所以可以直接看后面的示例进行理解。
示例解析
还是通过之前冲突示例进行分析,首先需要把所有的FOLLOW集列出来。
对于I2
,可以看到存在移进/归约冲突。根据SLR的基本思想,下一个输入符号为 * ,假设我们进行归约,查看FOLLOW(E)的集合,不存在即将输入的符号 * ,因此应该采用移入的操作。I9
中的分析同理,也可以知道应该采用移入的操作。因此得到的SLR分析表如下图所示。
SLR分析法核心要点:对于有冲突项目的状态(移进-规约冲突和归约-归约冲突)判断将要移入的符号是否在该产生式左部的FOLLOW集中,如果在则采取归约动作,否则采取移进动作。
可以通过下面这个例子,加深理解。
从图中可以看到,根据Follow(B)可以推出d采用归约动作,产生式为(4);
根据Follow(T)可以推出$,b采用归约动作,产生式为(2);
a不再任何一个FOLLOW集中,采用移入动作。
SLR分析表构造算法
构造算法表述十分严谨,但是一般不好理解。
SLR分析法,只对在Follow集中的输入符号采取归约动作,通过Follow确定能否归约。而LR(0)并没有考虑上下文环境,不需要Follow集的帮助。
注意:s是移入,r是归约,不要混淆。
SLR分析表中不存在冲突动作,不代表SLR分析法不存在冲突问题。
SLR分析法的问题
在I2
中,既可以采用移入动作,把 = 移入栈中,又满足 = 在Follow®中,可以采取归约动作,因此对于 = 号的输入,存在移入/归约冲突。由此可见,只是简单的根据Follow集中的信息进行冲突消解,并不能完全的解决冲突问题。
通过Follow集进行判断,SLR文法并不能确保冲突的完全消解,归约-归约冲突和移进-归约冲突都可能存在。
用 follow集来处理即出现移进-归约冲突的两条产生式,如果其 follow集相交为空则为 SLR文法,反之不是。当然,如果以上两种冲突都不存在自然是了。
示例补充
FOLLOW集
SLR分析表(自行推导)
根据下面的输入,分析每一步的动作。