如何解决 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
我相信改变会解决你的矛盾。
首先,我在这里已经提到了很多类似的问题,但无法解决冲突。
我的 .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
我相信改变会解决你的矛盾。