Parsing 如何理解LALR移位/减少算法

Parsing 如何理解LALR移位/减少算法,parsing,compiler-construction,lalr,Parsing,Compiler Construction,Lalr,我想读Niklaus Wirth写的。在第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 *

我想读Niklaus Wirth写的。在第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”的第一个“或”,因此会发生另一个缩减->T。如果这是正确的(我不确定是否正确),那么为什么不也用E替换,因为T代表规则“E”RHS的第一个“或”。是不是因为规则E有一个隐含的“EOF”(既然我们还没有达到EOF,它就不能减少)?或者是因为它在这一点上是不明确的(T也代表规则T第二个“或”的第一部分…,即T“*”F)?还是完全是别的原因


谢谢

解析器使用两个标准来决定下一步要采取的操作(移位或减少)。第一种情况是堆栈上的令牌与产品的右侧匹配。在步骤4之后,堆栈上的T与E=T生成相匹配,因此如果这是唯一的标准,那么它可能会在该点上减少。然而,解析器也在查看前瞻(即“剩余”中的第一个标记),以决定要采取的操作。没有以E“*”作为前缀的规则,因此缩减是无效的,唯一的操作是移位。在步骤20之后,E=T生成是有效的,因为(正如您所猜测的)前面的令牌实际上是一个EOF,它确实匹配

请注意,一些模棱两可的语法可能导致移位和reduce操作都有效。在这些情况下,野牛决定支持“转移”。有关更多详细信息,请参阅。然而,上面给出的语法并不含糊;一个前瞻性的标志足以让它变得明确