3

我正在尝试使用柠檬解析器生成器生成解析器表,但是.out我运行时生成的文件lemon grammar.y只包含自动机的状态。

有没有办法获得非终端的 goto 表,而不仅仅是自动机的状态?或者这只能通过阅读生成的代码来完成?是否有任何其他工具可以同时生成操作表和 goto 表?

PS:

一个简单语法的.out文件(由柠檬生成)如下所示:

State 0:
          start ::= * e
          e ::= * e PLUS t
          e ::= * t
          t ::= * t MUL f
          t ::= * f
          f ::= * LPAR e RPAR
          f ::= * ID

                          LPAR shift        1      
                            ID shift        4      
                         start accept
                             e shift        11     
                             t shift        6      
                             f shift        5      

State 1:
          e ::= * e PLUS t
          e ::= * t
          t ::= * t MUL f
          t ::= * f
          f ::= * LPAR e RPAR
          f ::= LPAR * e RPAR
          f ::= * ID

                          LPAR shift        1      
                            ID shift        4      
                             e shift        10     
                             t shift        6      
                             f shift        5      

State 2:
          e ::= e PLUS * t
          t ::= * t MUL f
          t ::= * f
          f ::= * LPAR e RPAR
          f ::= * ID

                          LPAR shift        1      
                            ID shift        4      
                             t shift        9      
                             f shift        5      

State 3:
          t ::= t MUL * f
          f ::= * LPAR e RPAR
          f ::= * ID

                          LPAR shift        1      
                            ID shift        4      
                             f shift        8      

State 4:
      (6) f ::= ID *

                             $ reduce       6      f ::= ID
                          PLUS reduce       6      f ::= ID
                           MUL reduce       6      f ::= ID
                          RPAR reduce       6      f ::= ID

State 5:
      (4) t ::= f *

                             $ reduce       4      t ::= f
                          PLUS reduce       4      t ::= f
                           MUL reduce       4      t ::= f
                          RPAR reduce       4      t ::= f

State 6:
      (2) e ::= t *
          t ::= t * MUL f

                             $ reduce       2      e ::= t
                          PLUS reduce       2      e ::= t
                           MUL shift        3      
                          RPAR reduce       2      e ::= t

State 7:
      (5) f ::= LPAR e RPAR *

                             $ reduce       5      f ::= LPAR e RPAR
                          PLUS reduce       5      f ::= LPAR e RPAR
                           MUL reduce       5      f ::= LPAR e RPAR
                          RPAR reduce       5      f ::= LPAR e RPAR

State 8:
      (3) t ::= t MUL f *

                             $ reduce       3      t ::= t MUL f
                          PLUS reduce       3      t ::= t MUL f
                           MUL reduce       3      t ::= t MUL f
                          RPAR reduce       3      t ::= t MUL f

State 9:
      (1) e ::= e PLUS t *
          t ::= t * MUL f

                             $ reduce       1      e ::= e PLUS t
                          PLUS reduce       1      e ::= e PLUS t
                           MUL shift        3      
                          RPAR reduce       1      e ::= e PLUS t

State 10:
          e ::= e * PLUS t
          f ::= LPAR e * RPAR

                          PLUS shift        2      
                          RPAR shift        7      

State 11:
      (0) start ::= e *
          e ::= e * PLUS t

                             $ reduce       0      start ::= e
                          PLUS shift        2      

----------------------------------------------------
Symbols:
    0: $:
    1: PLUS
    2: MUL
    3: LPAR
    4: RPAR
    5: ID
    6: error:
    7: start: LPAR ID
    8: e: LPAR ID
    9: t: LPAR ID
   10: f: LPAR ID
4

1 回答 1

4

Lemon 在单个块中输出操作表和 goto 表。goto 函数看起来像 shift 动作,除了前瞻是非终结符而不是终结符。

因此,如果我们采用状态 0:

 LPAR shift        1      
   ID shift        4      
start accept
    e shift        11     
    t shift        6      
    f shift        5      

前两行分别是读取 LPAR 和 ID 的操作。剩下的几行是 goto 函数,当 reduce 操作通过弹出堆栈来显示此状态时使用该函数。(与传统的 LR 机器不同,在 Lemon 中,accept动作在 goto 表中,而不是在输入结束伪终端的动作表中。)

尽管 LR 解析器的大多数描述都区分了动作表和 goto 表,但“shift”动作和 reduce 动作的“goto”部分之间几乎没有区别。这两者都将当前状态编号和符号推入解析器堆栈。不同之处在于 reduce 操作(例如reduce 6,表示“使用生产 6 减少”——它与状态 6 无关)首先将指示生产的右侧从堆栈中弹出并设置当前状态在执行 shift/goto 之前到堆栈顶部的新显示状态。(另一个区别是,在 shift 操作之后,需要读取一个新的前瞻标记,而 reduce 操作不消耗输入。)

于 2015-11-06T14:44:25.357 回答