Step1 - 构建增强语法
(0) E′ → S
(1) E → E + E
(2) E → E * E
(3) E → (E)
(4) E→id
Step2 - 找到闭包和 goto 函数来构造 LR (0) 项目。
闭包 (E′ → ∙ E) =
在 I 9上应用 goto
∵ goto 不能应用于 I 9,如 E → (E) 中的点。在最后一个位置。
Step3- FOLLOW的计算
应用规则 (1) 跟随
FOLLOW(B)= {$} (1)
E → E + E
比较 E → E + E 与 A → α B β
∴ α = ε, B = E, β = +E
∵ FIRST(β) = FIRST(+E) = {+}
∴FOLLOW 规则 (2a)
FOLLOW(E)= {+} (2)
应用规则 (3)
比较 E → E + E 与 A → α B
∴ A = E, α = E+, B = E
FOLLOW(E)= { FOLLOW(E)} (3)
E → E * E
应用FOLLOW的规则(2)和规则(3),我们得到
FOLLOW(E)= {*} (4)
FOLLOW(E)= { FOLLOW(E)} (5)
E → (E)
应用规则 (2)
比较 E → (E) 与 A → α B β
∴ 跟随 (E) = {)} (6)
规则 (3) 不能应用于此产生式
因为 E → (E) 不能与 A → α B 比较
E → 身份证
FOLLOW 的规则 (2) 和 (3) 不能应用于 E → id。因为 E → id 不能与 A → α B β 和 A → α B 进行比较。
结合(1)到(6),我们得到
跟随 (E) = {$, +,*, )}
Step4 - SLR解析表的构建
在解析表中,Row state 7, 8, column *, + 发生冲突。
在动作 [7, +], 动作 [7, *]
Action [8, +], Action [8, *] 发生了 shift-reduce 冲突。
关联和优先规则可以消除这种冲突。
解析字符串 id + id * id
堆 | 输入 | 行动 |
---|---|---|
0 | 身份证+身份证*身份证$ | Shift |
0 编号 3 | + 身份证 * 身份证 $ | Reduce by E → id |
0 E 1 | +id * id $ | Shift |
0 E 1 + 4 | 身份证*身份证$ | Shift |
0 E 1 + 4 ID 3 | * ID $ | Reduce by E → id |
0 E 1 + 4 E 7 | * ID $ | Conflict i. e. , s5 or r1 ∴ * has higher precedence then + ∴ Action [7,∗] = s5 So, shift-reduce, i.e., s5 |
0 E 1 + 4 E 7 * 5 | $ | Shift |
0 E 1 + 4 E 7 * 5 ID 3 | $ | Reduce by E → id |
0 E 1 + 4 E 7 * 5 E 8 | $ | Reduce by E → E * E |
0 E 1 + 4 E 7 | $ | Reduce by E → E + E |
0 E 1 | $ | accept |
以上解析解决了Action[7,*]中的冲突问题。
因此,Action [7, *] = s5 而不是 r1。
在解析字符串 id + id + id 时类似。
堆 | 输入 | 行动 |
---|---|---|
0 | 身份证+身份证+身份证$ | Shift |
0 编号 3 | + 身份证 + 身份证 $ | Reduce by E → id |
0 E 1 | +身份证 +身份证 $ | Shift |
0 E 1 + 4 | 身份证 + 身份证 $ | Shift |
0 E 1 + 4 ID 3 | +ID $ | Reduce by E → id |
0 E 1 + 4 E 7 | +ID $ | Conflict i. e. , Action [7, +] = s4 or r1. ∴ + is Associative (left). 0E1 + 4E7 will be reduced before shifting + ∴ Action [7, +] = r1 ∴ Reduce by E → E + E |
0 E 1 | +ID $ | Shift |
0 E + 4 | 编号 $ | Shift |
0 E + 4 ID 3 | $ | Reduce by E → id |
0 E + 4 E 7 | $ | Reduce by E → E + E |
0 E 1 | $ | 接受 |
因此,上面的解析显示了如何在 Action [7, +] 处解决 shift Reduce 冲突
所以,Action [7, +] = r1 而不是 s4
同理,Action [8, +] 和Action [8, *] 等其他入口也可以通过取字符串来解决。
id * id * id 和 id * id + id
分辨率是 Action [8, +] = r2 和
动作 [8, *] = r2。