yacc如何知道未来

时间:2016-06-29 18:02:20

标签: compiler-construction bison yacc lalr

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

是否会自动设计表格?

1 个答案:

答案 0 :(得分:1)

根据您提供的跟踪,我猜这个语法看起来像这样:

  • E→T | E + T
  • T→F | T * F
  • F→num

除非另有说明,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>