LR(0)
项目进一步分类:
归约项目
:形如
A→α.
的项目,其中α∈
(V
T ∪
V
N
)
*
。
它表示栈顶已形成句柄
α,
下一步动作应该是
归约
移进项目
:形如
A→α.aβ
的项目。其中,a∈VT
,α,β∈
(VT ∪
V
N
)
*
它表示期待从输入串中移进一个符号
,已待形成句柄
待约项目
:形如
A→α.Bβ
的项目。其中,
B∈
V
N
,
α,β∈
(V
T ∪
V
N
)
*。它表示期待从输入串中进行归约而
得到
B
,然后进一步得到
A
的全部右部
接受项目
:形如
S’→α.
的项目。
S’
是文法开始符,
以
S’
为左部的规则叧有一个(通过对一般文法拓广
得到的),所以,该归约项目是一个特殊的归约项
目,它表示整个句子已分析完毕,可以接受
把得到的每一个状态来进行转换可以得到一个NFA最后根据这个NFA我们可以转换成一个DFA当然这种方法比较繁琐而且工作量很大容易出错所以我们在这里不采用这种方法
通过 闭包函数 和 转换函数 , 直接求出 LR(0) 项目集规范族,再由转换函数建立 状态之间的连接关系得到识别活前缀的 DFA。
闭包函数:构造项目集 I 的 Closure(I)
I 的任何项目都属于 Closure ( I )
若 A→α .Bβ 属于 Closure (I),则对 任何 关于 B 的规则 B→γ , 项目 B→·γ 也属于 Closure (I )
重复执行上述两步骤,直到 Closure ( I )不再增大为止
状态转换函数 GO(I,X)
假定 I 是拓广文法 G′的任一项目集,X 为一 文法符号 ,状态 转换函数 GO(I,X) 的定义如下:
GO(I,X) = Closure(J)
其中,J={ A→αX.β│A→α.Xβ∈ I }
新状态的初始项目即圆点移动后的项目称为核。 即 J 称为 核
![](https://i-blog.csdnimg.cn/blog_migrate/5fe5ed62766378879d29853e9c58372e.png)
识别文法所有活前缀的DFA
使用 GO 函数可以将拓广文法 G′的 LR(0)项目集规范族联结成一个识别文法活前缀的DFA。具体步骤如下:
a) 置项目S′→ ·S 为初态集的核心项目,然后对其求闭包,CLOSURE({S′→·S} )得到初态的项目集
b) 对初态集或其它所构造的项目集应用转换函数 GO(I ,X)= Closure ( J )
c) 重复 b) 直到不出现新的项目为止
d) 状态转换函数 GO(I ,X) 建立项目集之间的关系
![](https://i-blog.csdnimg.cn/blog_migrate/de8957393ee35a3e35a0fa9c23df56d6.png)
LR(0)分析表
![](https://i-blog.csdnimg.cn/blog_migrate/3a289249e2391c50e301b7e403c461a1.png)
但是有些时候我们会发现,在构建这个LR(0)分析表的时候我们会产生移进规约冲突。具体可以看一道例题:
(0) S’→
S
(1) S→
rD
(2) D→
D,i
(3) D→
i
我们可以发现在标红的位置我们是不知道需要进行移进还是规约的这时候我们发现LR(0)的能力已经不够了。我们需要有一个能力更强大的武器来解决这个问题。
这里引入SLR(1)文法这里的S指的是simple即简单的。这里提一下例题当中是移进规约冲突但是实际上我们还是有规约规约冲突的
I ={
X→
α
·
bβ
,
移进项目
A→
α
·
,
归约项目
B→
α
·
归约项目}
存在移进
-
归约冲突和归约
-
归约冲突,但是只要满足:
FOLLOW(
A
) ∩ FOLLOW (
B
) = Ø
FOLLOW(
A
) ∩{
b
} = Ø
FOLLOW(
B
) ∩{
b
} = Ø
当状态
I
面临输入符号
a
时,则动作可以按一下规定决策
(1)
若
a = b
,
则移进
b
(2)
若
a
∈
FOLLOW
(A),
则使用
A→
α
归约
(3)
若
a
∈
FOLLOW
(B),
则使用
B→
α
归约
(4)
否则,
报错
具体操作可以看这个例子所示:
I ={ A1→α·a1β1 , 移进项目
A
2→
α
·a
2
β
2
,
…
A
m→
α
·a
m
β
m
,
B1
→α
·
,
归约项目
B2
→α
·
…
Bn
→α
·
}
当状态
I
面临输入符号
a
时,
(1)
若
a = a
i
,
则移进
a
i
(2)
若
a
∈
FOLLOW(B
i
),
则使
用
B
i→
α
归约
(3)
否则,
报错
这种解决冲突的方法称为
SLR(1)
方法。若文法的
LR(0)
项目集规范族中所有
项目集的冲突均能如此解决,则称此文法为
SLR(1)
文法
。
对
DFA C={I
0
,I
1
,…,I
n
},
构造
SLR
分析表
在构造
LR(0)
分析表的基础上更改
(1)
若
A→
α·aβ
∈
I
k
且
GO(
I
k
,a)=
I
j
,
则
ACTION[
k,a
]
=sj
(2)
若
A→
α·
∈
I
k
,
则
a
∈
FOLLOW
(A),
ACTION[
k,a
]=
rj
(
假定产生式
A→
α
是文法
G’
的第
j
个产生式)
(3)
若
S’→
S·
∈
I
k
,
则
ACTION[
k,#
]=
acc
(4)
若
GO(I
k
,A)=I
j
,
则
GOTO[k,A]=j
(5)
分析表中凡是不能用以上规则填入信息的空白格均置
上“报错标志”
SLR(1)
分析总结
求识别文法活前缀的
DFA
,即
LR(0)
项目集规范族
若
LR(0)
项目集规范族中不存在冲突项目集,则为
LR(0)
文法,也是
SLR(1)
文法;若存在冲突,则不
是
LR(0)
文法,但是如果可以用
SLR(1)
方法解决,
则是
SLR(1)
文法,可以构造
SLR(1)
分析表
基于
SLR(1)
分析表,可以对任意输入串进行
SLR(1)
分析