LL(1),LR(0),SLR(1),LALR(1),LR(1)对比与分析
前言:考虑到这几种文法如果把具体内容讲下来肯定篇幅太长,而且繁多的符号对初学者肯定是极不友好的,而且我相信看这篇博客的人已经对这几个文法已经有所了解了,本篇博客的内容只是对
这几个文法做一下对比,加深大家对这几个文法的理解。更详细的细节,初学者可以看看这个课件https://files-cdn.cnblogs.com/files/henuliulei/%E7%AC%AC5%E7%AB%A0.ppt,或者其他相关的博客。
一:五种文法的演变
1.1 LL(1)文法
LL(1)文法是自上而下的分析方法。
1.2 LR(0)分析方法
与LL(1)相对,LR(0)文法是下而上的分析方法,从左分析,从栈顶归约。
1.3LR(0) -> SLR的必要性
对于LR(0),由于分析中一遇到终态就归约,一遇到First集就移进,如果有一下状态I1,I1包含两个语法:
F->Y·+
F->Y·
那LR(0)就无法确定到底是移进还是归约了,而且LR(0)本身要求无移进规约冲突。
这就是为什么我们要引入SLR解决reduce-shift conflict(尽管不能完全解决该问题).
1.4 SLR的介绍
如果不仅考虑First,而且把Follow集也考虑在内,就可以一定程度上解决reduce-shift conflict.
还是以上语法:
F->Y·+B
F->Y·
如果FOLLOW(F) = {a, b},那么当我们遇到a与b时,就可以选择归约F;当我们遇到+时,就可以选择移进操作。
1.5 SLR -> LR(1)的必要性
SLR不能完全解决reduce-shift confict.
同样还是上面的语法:
F->Y·+B
F->Y·
如果 FOLLOW(F) = {a, b, +},那当我们遇到 + 符号时,就无法确定到底是选择移进操作得到F->Y+·B,还是归约F。
SLR不能完全解决reduce-shift conflict. 这就是为什么我们要选择LR(1) / LALR(1)了
SLR在方法中,如果项目集Ii含项目Aa.而且下一输入符号aÎFOLLOW(A),则状态i面临a时,可选用“用Aa归约”动作。
但在有些情况下,当状态i显现于栈顶时,栈里的活前缀未必允许把a归约为A,因为可能根本就不存在一个形如“bAa”的规范句型。因此,在这种情况下,用“ Aa ”归约不一定合适。 FOLLOW集合提供的信息太泛!
1.6LR(1)/LALR(1)介绍
具体可参考前言里面的PPT
二:LR(0),SLR(1),规范LR(1),LALR(1)的关系
首先LL(1)分析法是自上而下的分析法。LR(0),LR(1),SLR(1),LALR(1)是自下而上的分析法。
自上而下:从开始符号出发,根据产生式规则推导给定的句子。用的是推导
自下而上:从给定的句子规约到文法的开始符号。用的是归约
2. 1: SLR(1)与LR(0)的关系:
SLR(1)与LR(0):简单的LR语法分析技术(即SLR(1)分析技术)的中心思想是根据文法构造出LR(0)自动机。
LR(0):见到First集就移进,见到终态就归约
SLR(1)见到First集就移进,见到终态先看Follow集,与Follow集对应的项目归约,其它报错。
2.2: LR(1)与LR(0)的关系:
规范LR(1)语法分析技术的中心思想是根据文法构造出LR(1)自动机 ,而规范LR(1)自动机构造方法和LR(0)自动机的构造方法相同,只是多增加了向前搜索符号。
2.3 LR(1)与SLR(1)的关系
在构造SLR分析表的方法中 ,若项目集Ik中含有 Aàα• ,那么在状态k时,只要面临输入符号a∈FOLLOW(A) ,就确定用产生式 Aàα进行归约。
但是,在某些情况下,当状态k呈现于栈顶时,栈里符号串所构成的活前缀未必允许把α规约成A,因为可能没有一个规范句型含有前缀βAa,
因此,此时用产生式 Aàα进行归约未必有效。计算FOLLOW集合所得到的超前符号集合可能大于实际能出现的超前符号集。LR(1)很好的解决了该问题。
2.4:规范LR(1)与LALR(1)的关系:
LALR(1)是对LR(1)项集族I中具有同心项的项集进行合并得到I',然后根据I’进行分析的方法。
三:判断LL(1)SLR(1)LR(1)LALR(1)
3.1:LL(1)就是向前只搜索1个符号,即与FIRST()匹配,如果FIRST为空则还要考虑FELLOW。
3.2:LR需要构造一张LR分析表,此表用于当面临输入字符时,将它移进,规约(即自下而上分析思想),接受还是出错。
3.3:LR(0)找出句柄前缀,构造分析表,然后根据输入符号进行规约。
3.4:SLR(1)使用LR(0)时若有冲突,不知道规约,移进,活移进哪一个,所以需要向前搜索,则只把有问题的地方向前搜索一次。
3.5:LR(1) 在每个项目中增加搜索符;举个列子如有A->α.Bβ,则还需将B的规则也加入。
3.6:.LALR(1)就是假如两个产生式集相同则将它们合并为一个,几合并同心集。
四 总结
见到First集就移进,见到Follow集就归约。
LR(0):见到First集就移进,见到终态就归约
SLR(1)见到First集就移进,见到终态先看Follow集,与Follow集对应的项目归约,其它报错。
SLR分析法包含的展望信息是体现在利用了Follow(A)信息,可以解决“归约-归约”冲突
SLR分析法没有包含足够的展望信息,不能完成解决“移进-归约”冲突,需要改进。
LALR同心集合并不会产生“移进-归约”冲突 ,但会产生“归约-归约”冲突
下面是LR(0),SLR(1),LALR(1),LR(1)文法处理能力的比较,圆圈越大说明能力越强。
reference:
https://blog.csdn.net/acmdream/article/details/53375104
https://www.cnblogs.com/Alexkk/p/6033159.html?utm_source=itdadao&utm_medium=referral
http://www.cnblogs.com/sunshine-zzl/p/6719831.html
https://www.jianshu.com/p/26ddfa61d172