修复Lemon解析冲突

时间:2011-01-03 21:10:17

标签: parsing context-free-grammar lemon

我正在编写一个使用Flex和Lemon解析约束的小解析器。 Lemon报告了一些我无法摆脱的解析冲突。在上下文无关语法中是否有任何特殊的技巧来摆脱解析冲突?

语法如下。

// Reprint of input file "Constraint_grammar.y".
// Symbols:
//   0 $          5 NE        10 PLUS        15 NOT         20 error
//   1 IFF        6 GT        11 MINUS       16 LPAREN      21 constraint
//   2 AND        7 GTE       12 TIMES       17 RPAREN      22 bool_expr 
//   3 OR         8 LT        13 DIVIDE      18 VARIABLE    23 int_expr
//   4 EQ         9 LTE       14 POWER       19 INTEGER   
constraint ::= bool_expr.
bool_expr ::= LPAREN bool_expr RPAREN.
int_expr ::= LPAREN int_expr RPAREN.
bool_expr ::= int_expr LT int_expr.
bool_expr ::= int_expr GT int_expr.
bool_expr ::= int_expr EQ int_expr.
bool_expr ::= int_expr NE int_expr.
bool_expr ::= int_expr GTE int_expr.
bool_expr ::= int_expr LTE int_expr.
bool_expr ::= bool_expr AND bool_expr.
bool_expr ::= bool_expr OR bool_expr.
bool_expr ::= bool_expr IFF bool_expr.
int_expr ::= int_expr PLUS int_expr.
int_expr ::= int_expr MINUS int_expr.
int_expr ::= int_expr TIMES int_expr.
int_expr ::= int_expr DIVIDE int_expr.
int_expr ::= int_expr POWER int_expr.
bool_expr ::= NOT bool_expr.
int_expr ::= MINUS int_expr.
int_expr ::= VARIABLE.
bool_expr ::= VARIABLE.
int_expr ::= INTEGER.
%nonassoc IFF.
%left AND.
%left OR.
%nonassoc EQ NE GT GTE LT LTE.
%left PLUS MINUS.
%left TIMES DIVIDE.
%right POWER NOT.
%nonassoc LPAREN RPAREN.

错误如下。

State 28:
     (19) int_expr ::= VARIABLE *
     (20) bool_expr ::= VARIABLE *

                             $ reduce 20
                           IFF reduce 20
                           AND reduce 20
                            OR reduce 20
                            EQ reduce 19
                            NE reduce 19
                            GT reduce 19
                           GTE reduce 19
                            LT reduce 19
                           LTE reduce 19
                          PLUS reduce 19
                         MINUS reduce 19
                         TIMES reduce 19
                        DIVIDE reduce 19
                         POWER reduce 19
                        RPAREN reduce 19
                        RPAREN reduce 20  ** Parsing conflict **
State 40:
          bool_expr ::= bool_expr * AND bool_expr
          bool_expr ::= bool_expr * OR bool_expr
          bool_expr ::= bool_expr * IFF bool_expr
     (11) bool_expr ::= bool_expr IFF bool_expr *

                             $ reduce 11
                           IFF shift  4
                           IFF reduce 11  ** Parsing conflict **
                           AND shift  1
                            OR shift  3
                        RPAREN reduce 11

整个解析器生成器报告已经结束了。 http://pastebin.com/TRsV3WvK

任何人都知道我在这里做错了什么?我可以忽略这些冲突吗?

2 个答案:

答案 0 :(得分:1)

我希望通过区分布尔变量和整数变量来修复“状态28”冲突,使用符号表来帮助确定返回哪种类型的令牌。你可能有BOOL_VARIABLE和INT_VARIABLE。测试表明,这种变化摆脱了“国家28”的冲突。

通过更改IFF从nonassocleft的关联性,可以轻松删除“州40”冲突。是否有充分理由不将其联想起来?

答案 1 :(得分:0)

你有解析器冲突,这意味着你指定的语法不是明确的,即对于某些给定的终端符号输入,存在多个解析树。这很常见,但是如果我们想要一个明确的语法,我们需要指定消歧规则,例如关联性和优先级,这样我们总是可以只选择一个解析树。

我不确定你用什么样的约束来解析语法,但我很确定你想要一个不可思议的语法,编程语言(几乎)总是毫不含糊。 (但是如果约束来自某种自然语言源,那么你可能不得不使用更合适的解析器)我不确定解析器柠檬会做什么,如果你给它一个ambigous语法,可能只是喜欢其中一个转换在它的自动机中,它很可能导致你不想要的树。