Skip to content

算法Algorithm

SLR 分析表

SLR parsing · Simple LR parsing

保留LR(0)状态,只在左部FOLLOW集合上允许归约的确定解析方法。

形式陈述 ​

SLR(1) 保留LR(0)的项目自动机与状态栈,只改变归约表的填法。状态 I 中出现 A→α⋅ 时,不再把归约填满整行,而是只填到

a∈FOLLOW(A)

的列中。FOLLOW 由文法集合分析求得,表示 A 在任何合法句型中可能面对的后续 token。终结符边仍产生移进动作,非终结符边仍填 GOTO,增广完整项目仍只在输入结束处接受。

若每个 ACTION 格至多有一个动作,称这份文法是 SLR(1) 文法,通常简称 SLR。它的运行步骤与 LR(0) 完全相同;区别在于静态构表时更少地允许归约,并不是运行时临时回溯寻找“更合适”的规则。

直觉

完整项目说“右部已经齐了”,FOLLOW 再问“它若现在结束,下一个 token 能接在它后面吗?”一个输入 token 不能跟在 A 后面,就可排除在此刻把整段压成 A。

但 FOLLOW 把 A 的所有出现上下文混在一起。同一个 A 在另一个位置能跟 =,不保证它在当前项目状态中也能跟 =。所以这是一种可靠但可能过宽的上下文近似。过宽不会漏掉文法需要的归约,却可能保留冲突,使 SLR 无法给出确定动作。

例子与边界

用 FOLLOW 修复一个真实的 LR(0) 冲突 ​

取 r1:E→T+E,r2:E→T,r3:T→id。这里是右递归表达式文法。读到一个 T 后的状态为

I2={E→T⋅+E, E→T⋅}.

LR(0) 在 + 上既填移进,又因完整项目填归约 r2,发生冲突。实际 FOLLOW 集是

FOLLOW(E)={$},FOLLOW(T)={+,$}.

因此 SLR 只在 $ 上将 T 归约为 E;+ 列只剩移进。六状态的全部表如下:

状态 id + $ E T
0 s3 — — 1 2
1 — — acc — —
2 — s4 r2 — —
3 — r3 r3 — —
4 s3 — — 5 2
5 — — r1 — —

其中 I0 预测全部规则;I1 只含 E′→E⋅;I3 只含 T→id⋅;I4 含 E→T+⋅E 及开始解析 E,T 的闭包;I5 只含 E→T+E⋅。

解析 id+id 时,状态栈依次为

[0]→[0,3]→[0,2]→[0,2,4]→[0,2,4,3]→[0,2,4,2]→[0,2,4,5]→[0,1].

动作依次是移进 id、T→id、移进 +、移进 id、T→id、E→T、E→T+E,最后在 $ 接受。两次到达状态2时的动作不同,正是下一 token 为 + 还是 $ 的区别。

FOLLOW 也可能太宽 ​

考虑赋值文法:

S→L=R∣R,L→∗R∣id,R→L.

从初态识别 L 后,项目集含

S→L⋅=R,R→L⋅.

第一个项目要求可以移进 =。另一方面,S→L=R 让 = 属于 FOLLOW(L),L→∗R 又让 FOLLOW(L) 进入 FOLLOW(R),因此 = 也属于 FOLLOW(R)。SLR 遂在同一格放入 R→L 归约。

这个信息并非凭空产生:在 *R=R 一类句型中,内部的 R 确实可能面对 =。问题是当前栈只有作为整个句子开头的 L,若此时走 S→R→L,它后面应是结束标记,而不是赋值号。全局 FOLLOW 没保存这一区别。

规范 LR(1)在当前完整项目后附的向前看集合只有 {$},因此能够移进 = 而不发生冲突。不能以“SLR有冲突”推断这份文法有歧义,也不应随意删掉一条产生式来压掉报错。

推论与应用

SLR 不增加 LR(0) 状态数。若实际自动机有 q 个状态,构表除了原有项目/边枚举,还需计算 FOLLOW,并对每个完整项目填相应集合中的列;稠密表空间仍为 O(q(|V|+|Σ|))。固定文法的解析驱动成本仍为线性时间及最坏线性栈空间。

安全性来自 FOLLOW 的必要条件:合法句柄归约后面出现的 token 必在相应 FOLLOW 中,所以限制归约不会删掉一条合法最右推导所需的动作。若剩余每格唯一,驱动器便能确定地执行;若仍有冲突,算法报告的是适用条件失败,而不是凭启发式冒充同一可靠性定理。

一个实用检查顺序是:先列出冲突状态的完整项目与移进项目,再算涉及的 FOLLOW,最后问这些 FOLLOW 元素来自哪些文法出现位置。这样能区分真正的歧义与全局上下文合并造成的伪冲突,也能看清下一步是否需要 LR(1)。

参考资料
  • Stanford CS143, Lecture 8: Bottom-Up Parsing,slides 79–82、102:SLR归约条件与运行
  • Aho, Lam, Sethi, Ullman, Compilers, 2nd ed., 2007,§4.6:SLR构造及不能由SLR处理的文法
  • Cornell CS4120, LR(1) and LALR Parsing,局部向前看为何优于无上下文区分的归约
关系图谱6 个相邻概念 · 2 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组
类型化关系