如何解决 bison 中的 reduce reduce 冲突?

How to resolve reduce reduce conflicts in bison?

首先,我在这里已经提到了很多类似的问题,但无法解决冲突。

我的 .y 文件中有这篇文章

.
.
.
obj
    : INT { $$ = objNew(, INT_T); }
    | FLOAT { $$ = objNew(, FLOAT_T); }
    | STR { $$ = objNew(, STR_T); }
    ;

var
    : IDEN { $$ = varLookup(); }
    ;

atom
    : '(' expression ')' { $$ = ; }
    ;

index
    : '[' obj ']' { $$ = ; }
    ;

primary_expr
    : obj { $$ = objExpr(); }
    | var { $$ = varExpr(); }
    | atom { $$ = atmExpr(); }
    | expression index { $$ = idxExpr(, ); }
    ;

unary_expr
    : primary_expr { $$ = ; }
    | '+' unary_expr { $$ = unExpr(UPLUS, ); }
    | '-' unary_expr { $$ = unExpr(UMINUS, ); }
    ;

power_expr
    : unary_expr { $$ = ; }
    | power_expr '^' unary_expr { $$ = biExpr('^', , ); }
    ;

multiplicative_expr
    : power_expr { $$ = ; }
    | multiplicative_expr '*' power_expr { $$ = biExpr('*', , ); }
    | multiplicative_expr '/' power_expr { $$ = biExpr('/', , ); }
    ;

additive_expr
    : multiplicative_expr { $$ = ; }
    | additive_expr '+' multiplicative_expr { $$ = biExpr('+', , ); }
    | additive_expr '-' multiplicative_expr { $$ = biExpr('-', , ); }
    ;

relational_expr
    : additive_expr { $$ = ; }
    | relational_expr '>' additive_expr { $$ = biExpr('>', , ); }
    | relational_expr '<' additive_expr { $$ = biExpr('<', , ); }
    | relational_expr '=' additive_expr { $$ = biExpr('=', , ); }
    ;

referential_expr
    : relational_expr { $$ = ; }
    | referential_expr IS relational_expr { $$ = biExpr(IS, , ); }
    ;

conjunction_expr
    : referential_expr { $$ = ; }
    | conjunction_expr AND referential_expr { $$ = biExpr(AND, , ); }
    ;

disjunction_expr
    : conjunction_expr { $$ = ; }
    | disjunction_expr OR conjunction_expr { $$ = biExpr(OR, , ); }
    ;

conditional_expr
    : disjunction_expr { $$ = ; }
    | disjunction_expr '?' disjunction_expr ':' conditional_expr { $$ = trExpr('?', , , ); }
    ;

sequence
    : conditional_expr { $$ = seqChain(NULL, ); }
    | sequence ',' conditional_expr { $$ = seqChain(, ); }
    ;

assignment_expr
    : sequence { $$ = seqAssign(, NULL); }
    | sequence ASS assignment_expr { $$ = seqAssign(, ); }
    ;

expression
    : assignment_expr { $$ = ; }
    ;

statement
    : ';' { $$ = NULL; }
    | expression ';' { $$ = exprStmt(); }
    ;

routine
    : routine statement { $$ = rtnChain(, ); }
    | { $$ = NULL; }
    ;

program
    : routine { compile(); exit(0); }
    ;

.
.
.

这个语法产生了很多 reduce\reduce 冲突。例如:

State 81

   18 power_expr: unary_expr .
   19           | power_expr '^' unary_expr .

    '+'       reduce using rule 18 (power_expr)
    '+'       [reduce using rule 19 (power_expr)]

我有很多与此完全相似的冲突。但是我不明白这一点。
据我所知,它是说,当产生式是unary_expr或当它是power_expr '^' unary_expr然后看起来是'+'时,它面临着reduce\reduce冲突。但是为什么会有reduce\reduce冲突呢?当它有 power_expr '^' 部分时,它可以使用规则 19(并且应该使用,否则产生式将是语法中未定义的 power_expr '^' power_expr。)并且当没有 power_expr '^' 部分时,它不得不用规则18,这里哪里有歧义,怎么解决。

问题源于规则

primary_expr: expression index 

该规则不可能是正确的,因为它暗示可以通过将 [3] 应用于 expression a+b 来解析 a+b[3]。但它也可以被解析为好像写成 a+(b[3])。这种歧义产生了减少-减少冲突。

我们知道只有第二种解释是正确的,这强烈表明规则应该是

primary_expr: primary_expr index 

我相信改变会解决你的矛盾。