我们之前分析了SLR(1)方法,SLR(1)方法的S代表simple说明它是一个简单的LR(1)方法所以它也是会有一些问题的。我们在这里介绍LR(1)方法这个就会强大一些解决SLR(1)解决不了的一些问题。
我们在SLR(1)方法中解决冲突的方法是进行求FOLLOW集合来进行解决冲突。但是有些FOLLOW集合虽然求出来了但是它是在这个文法接受的句子中不会出现的!!!
例子:
0. S’→S
1. S→aAd
2. S→bAc
3. A→aec
4. A→bed
5. A→e
问题
I5 ={S→ae.c A→e.}
Follow(A) = {c,d}
分析
S’=>S=>aAd=>aed
S’=>S=>aec
对于活前缀ae,面临d应该规约,面临c应该移进对于aec 若使用A→e 进行规约,规约后符号栈中是 aAc,但是文法不存在aAc句型,S’=>S≠>aAc。
有些归约是无效的所以需要再限制归约的条件。
总结
SLR(1)用FOLLOW信息作为展望信息(叧对属于FOLLOW集的输入符号归约),缩小了归约范围
,消除了一些无效归约,解决了项目集中的一些简单的冲突尽管FOLLOW(A)中包含了所有含A的句型中A后的可能终结符,但并不是每个含有A的句型中,A的后面都可以出现Follow(A)中的每一个符号,所以SLR(1)未能从根本上消除所有无效归约。
对策
给每个LR(0)项目添加展望信息,即:添加句柄之后可能跟的终结符,因为这些终结符确实是规范句型中跟在句柄之后的。
若[A→α•Bβ]属于项目集I时,则[B→•γ]也属于I
把FIRST(β)作为用产生式归约的搜索符(称为向前搜索符),即把FIRST(β)作为用产生式B→γ归约的超前符号信息(用以代替SLR(1)分析中的FOLLOW(B)集),并把此搜索符号的集合也放
在相应项目的后面,这种处理方法即为LR(1)方法。
LR(1)方法按每个具体的句型设置展望信息。
如果存在如下的一些句型
…αAa…,…βAb…,…γAc…,则FOLLOW(A)={a,b,c}
处理到句型…αA,只当输入符号为a时归约
处理到句型…βA,只当输入符号为b时归约
处理到句型…γA,只当输入符号为c时归约
LR(1)项目集的构造
相关定义:LR(1)项目
形如(A→α•β,a)的二元式称为LR(1)项目。其中,A→αβ是文法的一个产生式,a是终结符,称为向前搜索符
LR(1)项目= LR(0)项目+向前搜索符
注意
(A→α•β,a)的含义:预期当栈顶句柄αβ形成后,待输入的符号为a。此时,α在栈内,β还未入栈,即它展望了句柄后的一个符号
S’→.S, #的含义:若将γ(S→γ)规约为S,必须面临输入符号为#才可以
对于多数程序设计语言,向前展望一个符号就足以决定归约不否,所以只研究LR(1)
LR(1)项目集族的构造
1 拓展文法, 同LR(0)
2 将S’→.S, # 作为LR(1)初始项目集的核
3 项目I的闭包closure(I)
(1)I的任何项目都属于closure(I);
(2)若[A→α.Bβ,a]∈closure(I),B→γ为一产生式,则对 ∀b∈FIRST(βa),如果[B→.γ,b]∈closure(I)原来不在CLOSURE(I)中,则把它加进去
重复(2),直到CLOSURE(I)不再扩大为止
例子:求出下列文法的Closure(I)
(0) S’→S
(1) S→BB
(2) B→aB
(3) B→b
I={S’→.S, #}
Closure(I)={ S’→.S, # S→.BB, # B→.aB, a/b B→.b, a/b}
(3) 转换函数的构造
GO(I,X)= CLOSURE(J)
其中:
I为LR(1)的项目集,X为一文法符号 J={任何形如[A→αX•β,a]的项目|[A→αX•β,a]属于I}
在执行转换函数GO时,搜索符并不改变
例:
(0) S’→S
(1) S→BB
(2) B→aB
(3) B→b
I={ S’→.S, # S→.BB, # B→.aB, a/b B→.b, a/b}
Go(I, B) ={ S→B.B, # B→.aB, # B→.b, #}
在这里注意B→.aB和B→.b后面的向前搜索符发生了改变!!!
LR(1)分析表的构造
设LR(1)项目集族C={I0 ,I1 ,…In}
(1)若项目[A→α.aβ,b]属于Ik且Go[Ik ,a]=Ij,a为终结符,则置Action[k,a]=Sj;
(2)若项目[A→α.,a]属于Ik,置Action[k, a]=rj,j为产生式 A→α在文法中的编号;
(3)若项目[S’→S.,#]属于Ik,则置Action[k, #]=acc;
(4)若Go[Ik ,A]=Ij,则置Goto[k,A]=j;
(5)不能用(1)-(4)条填入信息的空白格均填“出错标志”
例题:
0. S’→S
1. S→aAd
2. S→bAc
3. A→aec
4. A→bed
5. A→e
设文法G[S’]:
构造该文法的LR(1)项目集族
判断该文法是否 LR(1) 文法 若是,构造 LR(1) 分析表 若不是,请说明理由
