LR(0)文法要求文法的每一个LR(0)项目都不含有冲突的项目,这个条件比较苛刻。对于大多数程序设计语言来说,一般都不能满足LR(0)文法的条件。
例如:
不难看出在状态
I2中既存在规约项目,又存在移进项目,因而这个文法不是LR(0)文法。
为了对语言句子进行确定性的分析,需要解决冲突。可以采用对含有冲突的项目集向前查看一个输入符号的办法来解决冲突,这种分析法称为简单的LR分析法,即SLR(1)分析法。
分析构造LR(0)分析表的方法,易看出是分析表出现多重定义的原因在于其中的规则2。即对于每一个项目集
Ik中的规约项目
A→α⋅,不管当前输入符号是什么,都将ACTION
表中第k行的各个元素均置为
rj。
因此当一个LR(0)项目集闺范族中存在一个含有冲突的项目集,例如:
Ik={X→δ⋅bB,A→α⋅,B→r⋅}
当遇到符号b
时,必然会出现多重定义元素。
如要解决则需要向前查看一个输入符号以考察当前所处环境。对规约项目
A→α⋅和
B→r⋅,只需要考察当讲句柄
α或r
规约为A
或B
时,直接跟在A
或B
后面的终结符集合即FOLLOW(A)
和FOLLOW(B)
互不相交且不包含移进符号b,即满足:
FOLLOW(A)∩FOLLOW(B)=∅
FOLLOW(A)∩{b}=∅
FOLLOW(B)∩{b}=∅
那么,当状态k
面临输入符号a
是,可按下列规则解决冲突:
- 若
a=b
则移进
- 若
a∈FOLLOW(A),则用规则
A→α进行规约
- 若
a∈FOLLOW(B),则用规则
B→r进行规约
- 此外都报错
SLR分析法的基本思想
这种用来解决分析动作冲突的方法称为SLR(1)方法。如果对于一个文法的某些LR(0)项目集或LR(0)分析表中所含有的动作冲突都能用SLR(1)方法解决,则称这个文法是SLR(1)文法。
SLR(1)分析表的构造
SLR(1)分析表的构造与LR(0)分析表的构造基本相同。(LR(0)分析表的构造方法在这里)
仅对LR(0)分析表构造方法的第二步进行如下修改:
若规约项目
A→α⋅属于
Ik,则对任何终结符
α∈FOLLOW(A)置
ACTION[k,a]=rj,其中
A→α为文法的第j条的规则。