SLR(1)分析法只是简单地考察下一个输入符号b
是否属于与归约项目
相关联的FOLLOW(A)
,但
只是归约的一个必要条件,而非充分条件。
假设栈内的符号串为 $ $ \delta\alpha $ ,规约之后变为 $ $\delta A$ ,当前读到的输入为a
,若文法中不存在以 $ $\delta a $ 为前缀的规范举行,那么这种规约就无效了。并不是FOLLOW(A)中的每个元素在A的所有举行中都会出现在A的后面。
LR(1)分析法的思想
当师徒用某一规则
规约栈顶的符号
时,不仅应该查看栈中符号串
,还应向前扫视一个输入符号a
,只有当
确实构成文法某一规范句型的前缀时,才能用此规则进行规约。
因此,可以考虑在原来LR(0)项目集中增加更多的展望信息,这些信息有助于克服动作冲突和排除无效规约,也就是需要重新定义称之为**LR(1)**的项目。
LR(1)项目
一个LR(1)项目是一个二元组[
],其中
是一个LR(0)项目,每个a
是终结符,称它为展望符或搜索符。
当$\beta \not= \epsilon $时,搜索是无意义的。
当
时,搜索符a
明确指出当[
]是栈顶状态的一个LR(1)项目时,仅在输入符号是a
时才能用
规约,而不是对FOLLOW(A) 中的所有符号都用
规约。
LR(1)项目集族构造方法
构造LR(1)项目集I
的闭包函数
I
的任何项目都属于CLOSURE(I)
- 若项目
属于
CLOSURE(I)
, 是文法中的一条规则, ,则 也属于CLOSURE(I)
- 重复第二步直到
CLOSURE(I)
不再增大为止
转换函数构造
令I
是一个LR(1)项目集,X
是一个文法符号,函数
总结
多数情况下同一个文法的LR(1)项目集的个数比LR(0)项目集的个数要多,这是因为对同一个LR(0)项目集由于搜索符的不同而对应着多个LR(1)项目集。
当一个文法是LR(0)文法,则一定是一个SLR(1)文法,也是LR(1)文法。反之却不一定成立。