考完编译原理有一段时间了,记得当时都被以上这五种文法搞懵了,所以希望写篇文章帮助那些正在学习的人。以下内容是依据龙书中文版讲解的,由于老师不同可能某些地方大同小异,如有什么纰漏之处还请指出,多谢~
以下文章参考了:LL LR SLR LALR 傻傻分不清。
首先来看张图,上图是四种文法的包含关系,即 LR(1)文法范围最大,而 LR(0)文法范围最小。同时也说明了四种文法分析过程的强弱,即 LR(1)文法分析最强,而 LR(0)文法分析最弱。
那为什么没有 LL(1)文法呢?因为它和上面的四种文法是不同的。
LL(1)分析法是自上而下的分析法。LR(0),LR(1),SLR(1),LALR(1)是自下而上的分析法。
自上而下:从开始符号出发,根据产生式规则推导给定的句子。用的是推导。
自下而上:从给定的句子规约到文法的开始符号。用的是归约。
下面就主要来讲解他们的不同点, LL(1)单独讲,其他四种文法分析过程基本有三大步:写出自动机(即 LR(0)或 LR(1)项集族,后面都称作自动机) -> 构造文法分析表-> 进行文法分析过程。其中后两步都是类似或者说几乎完全一样的,第一步中的自动机有两种: LR(0)自动机和 LR(1)自动机。LR(0) 和 SLR文法分析用的是 LR(0)自动机,LR(1)和 LALR文法分析用的是 LR(1)自动机。而LR(1)自动机构造方法和LR(0)自动机的构造方法相同,只是多增加了向前搜索符号。
一、LL(1)文法分析
分析过程:
LL(1)分析又称预测分析,首先将文法拆分到最小,即不带写出“|”的产生式,并写出每条产生式的 select集。然后,针对输入串写出预测分析表,表的最左一列为非终结符,最上一行为输入串中出现的终结符,注意要包括句子括号“#”。
然后就是进行预测分析了,由于上课老师是在黑板上画的,我又懒得写……so……大家自己动手吧。预测分析的过程和后面的 LR分析过程大体类似,最上一行应该有的项是:步骤、符号栈、剩余串和动作。其中动作无非就是匹配和移近,当符号栈栈顶符号和剩余串最左边符号相同时则匹配,反之移近。由哪条产生式移近应根据上面的预测分析表来决定,即符号栈栈顶的非终结符和剩余串最左部的终结符对应的产生式。如果没有与之对应的产生式则匹配出错,给出的输入串不是该文法的句子,如果匹配完毕则 acc(接受)。
LL(1)文法判定:
主要有两种方式,一是依靠 select集,如果对于产生式左部相同的任意两条产生式的 select集相交为空 且 两者不能同时推出空,则是LL(1)文法。二是如果预测分析表中没有多重入口(即分析表的一格中只有一个产生式)则为LL(1)文法。
二、LR(0)文法分析
分析过程:
首先要拓广文法,即如果文法开头不是一个非终结符到另一个非终结符的产生式则需要加入,如加入 S'->S .
然后需要构造 LR(0)自动机,就是加入了一个圆点,圆点后的符号是即将处理的符号,如果圆点后是非终结符时,则要写出该终结符为产生式左部的所有产生式。反复以上过程,直到不再扩大。给它们编号并写出读入下一个符号(即圆点后的符号)会跳转到哪。
然后构造 LR(0)分析表,左侧为项集族编号,上部为终结符和非终结符。中间内容表示该编号的项集族遇到非终结符应该移近还是归约,数字为跳转到的项集族编号,如果圆点到了产生式的最右边则应归约,反之移近。遇到终结符填入相应的项集编号即可。如 (0,a) 即第0行a列对应的是 S2,其意思为对于项集族 I0,如果下一个读入的符号为a,则移进到项集族 I2 ;又如第4行对应的都是 r1,其意思为对于项集族 I4,如果下一个读入的符号为一个终结符则需要按照编号为 (1) 的产生式进行归约;再如 (0,E) 对应的是 1,其意思为对于项集族 I0,如果下一个读入的符号为非终结符 E,则移进到项集族 I1.
下一步就是分析过程了,由于没有针对这个文法的分析过程,最后面会单独讲解,下面的文法就不提分析过程的表了。几乎都是一样的。
LR(0)文法判定:
如果文法对应的自动机中不存在移进-归约冲突和归约-归约冲突则为 LR(0)文法。换句话说LR(0)文法分析不能解决这两种冲突,所以范围最小。移进-归约冲突就是在同一个项集族中同时出现了可以移进的产生式和可以归约的产生式。归约-归约冲突类似。
三、SLR文法分析
分析过程:
拓广文法、写自动机、分析过程表与 LR(0)文法相同。但是由于可能存在移进-归约冲突,所以 SLR分析表可能存在多重入口(即同一格中既有移进又有归约)。
SLR文法判定:
SLR文法不存在归约-归约冲突,有可能存在移进-归约冲突,但是如果可以用 follow集解决则是 SLR文法。换句话说,SLR文法分析过程可以解决归约-归约冲突,但是不一定能解决移进-归约冲突。用 follow集来处理即出现移进-归约冲突的两条产生式,如果其 follow集相交为空则为 SLR文法,反之不是。当然,如果以上两种冲突都不存在自然是了。
四、LALR文法分析
分析过程:
拓广文法与前面一致。
在自动机这块,我们需要构造的是 LR(1)自动机,与 LR(0)自动机的不同是多了向前搜索符。感觉自己写的太多了,搜索符怎么确定以后在评论里说吧。LALR需要合并同心集,即合并产生式相同但是向前搜索符不同的项集族。
由于合并了同心集,所以 LALR分析表也应该做出相应的改变,例如合并了 I3和 I6,则对应的格中应填 S36 .
LALR文法判定:
有个结论是合并同心集不会产生新的移进-归约冲突,但是会产生新的归约-归约冲突,如果没产生冲突就是 LALR 文法,反之不是。
五、LR(1)文法分析
分析过程与 LALR文法相同。
LR(1)文法判定:
因为 LR(1)文法的范围比较大,所以文法几乎都是 LR(1)的,现在知道的只有当合并同心集产生了归约-归约冲突时才只属于LR(1)文法,而不属于其他文法。
注意,根据最开始的那张图可以知道,是小的文法一定是大的文法。这一点需要注意。
分析过程表:
上面四种文法的分析过程可以说都是一模一样的,根据状态栈栈顶和剩余串最左部符号查分析表,如果是移进就将数字和非终结符分别填入两个栈中。如果是归约,先将状态栈栈顶和符号栈栈顶出栈,然后将非终结符入符号栈,根据当前状态栈栈顶和剩余串最左部符号查分析表,并将数字填入状态栈。
原文链接:https://blog.csdn.net/zuzhiang/article/details/79047743