LR(1)分析法

SLR(1)分析法只是简单地考察下一个输入符号b是否属于与归约项目 A α A\rightarrowα 相关联的FOLLOW(A),但 b F O L L O W ( A ) b\in FOLLOW(A) 只是归约的一个必要条件,而非充分条件。

假设栈内的符号串为 $ $ \delta\alpha $ ,规约之后变为 $ $\delta A$ ,当前读到的输入为a,若文法中不存在以 $ $\delta a $ 为前缀的规范举行,那么这种规约就无效了。并不是FOLLOW(A)中的每个元素在A的所有举行中都会出现在A的后面。

LR(1)分析法的思想

当师徒用某一规则 A α A \rightarrow{\alpha} 规约栈顶的符号 α \alpha 时,不仅应该查看栈中符号串 δ α \delta \alpha ,还应向前扫视一个输入符号a,只有当 δ A a \delta Aa 确实构成文法某一规范句型的前缀时,才能用此规则进行规约。

因此,可以考虑在原来LR(0)项目集中增加更多的展望信息,这些信息有助于克服动作冲突和排除无效规约,也就是需要重新定义称之为**LR(1)**的项目。

LR(1)项目

一个LR(1)项目是一个二元组[ A α β a A \rightarrow{\alpha·\beta,a} ],其中 A α β A \rightarrow{\alpha·\beta} 是一个LR(0)项目,每个a是终结符,称它为展望符或搜索符

当$\beta \not= \epsilon $时,搜索是无意义的。

β = ϵ \beta = \epsilon 时,搜索符a明确指出当[ A α β a A \rightarrow{\alpha·\beta,a} ]是栈顶状态的一个LR(1)项目时,仅在输入符号是a时才能用 A α A \rightarrow{\alpha} 规约,而不是对FOLLOW(A) 中的所有符号都用 A α A\rightarrow{\alpha} 规约。

LR(1)项目集族构造方法

构造LR(1)项目集I的闭包函数

  1. I的任何项目都属于CLOSURE(I)
  2. 若项目 [ A α B β a a ] [A \rightarrow{\alpha·B\beta}a,a] 属于CLOSURE(I) B r B \rightarrow{r} 是文法中的一条规则, b F I R S T ( β a ) b\in FIRST(\beta a) ,则 [ B r b ] [B \rightarrow{·r},b] 也属于CLOSURE(I)
  3. 重复第二步直到CLOSURE(I)不再增大为止

转换函数构造

I是一个LR(1)项目集,X是一个文法符号,函数
G O ( I , X ) = C L O S U R E ( J ) J = { [ A α X β a ] [ A α X β a ] I } GO(I,X) = CLOSURE(J) \\ J = \{[A \rightarrow{\alpha X·\beta},a] | [A \rightarrow{\alpha ·X\beta},a] \in I\}

总结

多数情况下同一个文法的LR(1)项目集的个数比LR(0)项目集的个数要多,这是因为对同一个LR(0)项目集由于搜索符的不同而对应着多个LR(1)项目集

当一个文法是LR(0)文法,则一定是一个SLR(1)文法,也是LR(1)文法。反之却不一定成立。

猜你喜欢

转载自blog.csdn.net/hjc256/article/details/90580771