我正在尝试阅读Niklaus Wirth 的Compiler Construction。在第 23 页,他开始描述 LALR 如何在x*(y+z)
给定以下语法的情况下解析表达式:
E = T | E "+" T. expression
T = F | T "*" F. term
F = id | "(" E ")". factor
他继续将减少显示为:
Action Stack Remaining
1 x * (y + z)
2 S x * (y + z)
3 R F * (y + z)
4 R T * (y + z)
6 S T* (y + z)
7 S T*( y + z)
8 S T*(y + z)
9 R T*(F + z)
10 R T*(T + z)
11 R T*(E + z)
12 S T*(E+ z)
13 S T*(E + z )
14 R T*(E + F )
15 R T*(E + T )
16 R T*(E )
17 S T*(E)
18 R T*F
19 R T
20 R E
动作是 S(表示移位)或 R(表示减少……为了清楚起见,我添加了行号)。所以我想我了解如何从步骤 1 到 4 以及从 4 到 20,但我不了解 4 本身。例如,步骤 1 将 x 压入堆栈。x 表示规则“F”的 RHS,因此会发生缩减 -> F。F 表示规则“T”的第一个“OR”,因此可能会发生另一个缩减 -> T。如果这是正确的(我不是确定是吗?),那么为什么不将 T 也替换为 E,因为 T 代表规则“E”的 RHS 的第一个“或”。是不是因为规则 E 有一个隐含的“EOF”可以这么说(因为我们还没有达到 EOF,所以它不能减少)?或者是因为它在这一点上是模棱两可的(T也代表规则T的RHS的第二个“OR”的第一部分......即,T "*" F)? 还是完全是别的东西?
谢谢!