如何解决减少减少野牛的冲突?

问题描述

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

我的 .y 文件中有这个片段

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

expression
    : assignment_expr { $$ = $1; }
    ;

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

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

program
    : routine { compile($1); 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 冲突呢?当它有 power_expr '^' 部分时,它可以使用规则 19(并且应该使用,因为否则产生式将是 power_expr '^' power_expr 这在语法中没有定义。)并且当它没有 power_expr '^' 部分时,它必须使用规则 18。这里的歧义在哪里,以及如何解决

解决方法

问题源于规则

primary_expr: expression index 

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

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

primary_expr: primary_expr index 

我相信改变会解决你们之间的冲突。