我们之前分析了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
问题
I
5
={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={I
0
,I
1
,…I
n
}
(1)
若项目
[A→
α.
aβ,b]
属于
I
k
且
Go[
I
k
,a]=
I
j
,
a
为终结符,则置
Action[k,a]=
S
j
;
(2)
若项目
[A→
α.
,a]
属于
I
k
,置
Action[k, a]=
r
j
,
j
为产生式
A→
α
在文法中的编号;
(3)
若项目
[S’→
S.
,#]
属于
I
k
,则置
Action[k,
#
]=
acc
;
(4)
若
Go[I
k
,A]=I
j
,则置
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)
分析表
若不是,请说明理由
