yacc怎么知道在第10行中转移*
而不是减少T to E
STACK INPUT BUFFER ACTION
$ num1+num2*num3$ shift
$num1 +num2*num3$ reduc
$F +num2*num3$ reduc
$T +num2*num3$ reduc
$E +num2*num3$ shift
$E+ num2*num3$ shift
$E+num2 *num3$ reduc
$E+F *num3$ reduc
$E+T *num3$ shift /////****//
E+T* num3$ shift /////****//
E+T*num3 $ reduc
E+T*F $ reduc
E+T $ reduc
E $ accept
是否会自动设计表格?
答案 0 :(得分:1)
根据您提供的跟踪,我猜这个语法看起来像这样:
除非另有说明,yacc
使用LALR(1)解析算法,该算法使用前瞻标记来帮助在确定是执行移位还是减少操作时断开关系。在您指出的那一点上,解析器在其堆栈上有T
,前瞻为*
。请注意,在语法中,*
符号无法在任何派生中合法地遵循T
非终结符(正式地,*
∉跟随(T
)) 。这意味着解析器知道不会在这里减少,因为LALR(1)永远不会减少不在给定非终结符的FOLLOW集中的前瞻。
要了解其工作原理,您可以为此语法构造LALR(1)解析自动机,并查看与每个项目关联的前瞻。在该状态下,将有两个项目,即表格
的已完成项目T→F
以及以下转移项目:
T→T。* F
reduce项目的前瞻设置中不会有*
(我相信它只有$
),因此解析器的LALR(1)状态将如下所示:
T→F。[$]
T→T。* F [$]
因此,当解析器看到*
时,它知道不执行缩减而是移位,因为为reduce项设置的前瞻不包含*
。< / p>