【问题标题】:How do I fix this parsing conflict?如何解决此解析冲突?
【发布时间】:2019-08-13 12:25:37
【问题描述】:

我有一个用柠檬写的小语法导致解析冲突。

这是导致冲突的语法部分:

selection_statement ::= KWD_IF LPAREN expression RPAREN statement.
selection_statement ::= KWD_IF LPAREN expression RPAREN statement KWD_ELSE statement.

我已经看到this 的回答,但它只适用于野牛/yacc 我不知道如何在柠檬中复制它。

解决此解析冲突的最佳方法是什么?

提前致谢。

【问题讨论】:

    标签: parsing lemon


    【解决方案1】:

    Lemon 实现precedence rules 的方式与 Bison 相似但不完全相同,并且该功能可用于解决您遇到的 "dangling else" shift/reduce 冲突,因为它通常应用于 bison .

    Lemon 和 Bison 优先声明之间有两个主要区别:

    1. Bison 提供%precedence 作为%left%right%nonassoc 的替代品。但是,%nonassoc 通常可以在更适合%precedence 的任何地方使用。

    2. 在 Bison 中,您可以使用 %prec TERMINAL 显式声明产生式的优先级。在 Lemon 中,您可以通过在生产后放置 [TERMINAL] 来做同样的事情。 (这在上面链接的手册的优先规则部分中进行了解释。)

    此外,Bison 允许您将双引号字符串用于终端,这是 Lemon 中不可用的功能。

    综上所述,您可以将 Bison solution 调整为 Lemon,如下所示:

    /* LEMON (non-terminals abbreviated) */             /* Bison (from linked answer) */
    %nonassoc KWD_IF                                    %nonassoc "then"
    %nonassoc KWD_ELSE                                  %nonassoc "else"
    %%                                                  %%
    sel: KWD_IF LPAREN exp RPAREN stm. [KWD_ELSE]       stm: "if" "(" exp ")" stm            %prec "then"
       | KWD_IF LPAREN exp RPAREN stm KWD_ELSE stm.        | "if" "(" exp ")" stm "else" stm
    

    也可以使语法明确,但工作量更大。在链接的 Wikipedia 条目中,有一个示例说明如何执行此操作。

    【讨论】:

      【解决方案2】:

      所写的语法模棱两可且不正确,因为您实际上不希望在另一个 ELSE 前面允许没有 ELSE 的选择语句。在这种情况下,else 应该绑定到内部选择语句。

      你可以这样修复它:

      statement ::= open_sel
      statement ::= closed_sel
      statement ::= other
      
      open_sel ::= KWD_IF LPAREN expression RPAREN open_sel
      open_sel ::= KWD_IF LPAREN expression RPAREN other
      
      closed_sel ::= KWD_IF LPAREN expression RPAREN closed_sel
      closed_sel ::= KWD_IF LPAREN expression RPAREN closed_sel KWD_ELSE statement
      closed_sel ::= KWD_IF LPAREN expression RPAREN other KWD_ELSE statement
      

      它很复杂而且很繁琐,如果你有多种语句,比如 if...else,情况会变得更糟,这就是人们通常依赖解析器生成器中的默认冲突解决方案的原因。

      解析器生成器工具的作者知道这一点,因此几乎每个解析器生成器都有冲突解决规则,使 if...else 无需像这样重构语法即可工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-02-19
        • 2013-03-01
        • 2017-07-03
        • 2021-04-10
        • 2012-01-09
        • 2016-02-22
        • 2013-11-09
        • 1970-01-01
        相关资源
        最近更新 更多