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

Bison 如何解决和减少野牛的冲突?,bison,yacc,reduce-reduce-conflict,Bison,Yacc,Reduce Reduce Conflict,首先,我在这里已经提到许多类似的问题,但无法解决冲突 我的.y档案里有这篇文章 . . . obj : INT { $$ = objNew($1, INT_T); } | FLOAT { $$ = objNew($1, FLOAT_T); } | STR { $$ = objNew($1, STR_T); } ; var : IDEN { $$ = varLookup($1); } ; atom : '(' expression ')'

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

我的.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('*', $1, $3); }
    | multiplicative_expr '/' power_expr { $$ = biExpr('/', $1, $3); }
    ;

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

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

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

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

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

conditional_expr
    : disjunction_expr { $$ = $1; }
    | disjunction_expr '?' disjunction_expr ':' conditional_expr { $$ = trExpr('?', $1, $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); }
    ;

.
.
.
我有很多类似的冲突。但我不明白这一点。

据我所知,这是说,当生产是
uniary\u expr
或当生产是
power\u expr'^'uniary\u expr
时,然后它看起来是
+'
,它面临着一个reduce\reduce冲突。但是为什么会有reduce\reduce冲突呢?当它有
power\u expr'^'
部分时,它可以使用规则19(并且应该使用,因为否则生产将是
power\u expr'^'power\u expr
,这在语法中没有定义)。当它没有
power\u expr'^'
部分时,它必须使用规则18。这里的歧义是从哪里产生的,以及如何解决它。

问题源于规则

primary_expr: expression index 
该规则不可能是正确的,因为它意味着可以通过将
[3]
应用于
表达式
a+b
来解析
a+b[3]
。但它也可以被解析为编写成
a+(b[3])
。这种模糊性产生了减少冲突的效果

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

primary_expr: primary_expr index 

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

问题源于规则

primary_expr: expression index 
该规则不可能是正确的,因为它意味着可以通过将
[3]
应用于
表达式
a+b
来解析
a+b[3]
。但它也可以被解析为编写成
a+(b[3])
。这种模糊性产生了减少冲突的效果

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

primary_expr: primary_expr index 

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

请展示你的整个语法(或者展示一个完整的简化语法,它展示了同样的问题)。问题无疑存在于语法中看不见的部分。我可以猜出原因,但我更想知道我在说什么。@rici我已经添加了整个语法。现在检查一下。我很高兴我没有尝试二次猜测,因为我会猜错的。你试过跑步吗?@akim我想它在windows下不起作用。我得到了“--warning”的
bison:invalid参数“counterexamples”
错误。请显示您的整个语法(或显示显示相同问题的完整简化语法)。问题无疑存在于语法中看不见的部分。我可以猜出原因,但我更想知道我在说什么。@rici我已经添加了整个语法。现在检查一下。我很高兴我没有尝试二次猜测,因为我会猜错的。你试过跑步吗?@akim我想它在windows下不起作用。我得到了
bison:invalid参数'-warning'
error的'counterexamples',非常感谢。它立即解决了所有的reduce\reduce冲突。但你是怎么发现的?这是你的经历吗?或者我也可以根据野牛的产量来找到它?(这是我第一次使用yacc/bison)@SouravKannanthaB:我是通过在你的语法中查找
表达式的用法找到它的。这是基于经验的预感。一般来说,当您在状态表中看到意外的缩减时,您需要反向工作以回答“解析器如何实现此缩减?”;一个文本编辑器可以让你轻松地搜索文本(“ToState81”,例如),它可以让你更容易地在bison的状态表中向后导航output@SouravKannanthaB:另一件事是,您的注意力集中在
^
的制作上,无论是在您的问题文本中还是在您最初选择的要展示的制作中。但这不是问题所在。问题的关键是触发它的先行标记(或者更可能是一组大的先行标记),因为可能涉及到一个大的缩减链。(这只是一个启发,但至少可以让你找到正确的地方。)非常感谢。它立即解决了所有的reduce\reduce冲突。但你是怎么发现的?这是你的经历吗?或者我也可以根据野牛的产量来找到它?(这是我第一次使用yacc/bison)@SouravKannanthaB:我是通过在你的语法中查找
表达式的用法找到它的。这是基于经验的预感。一般来说,当您在状态表中看到意外的缩减时,您需要反向工作以回答“解析器如何实现此缩减?”;一个文本编辑器可以让你轻松地搜索文本(“ToState81”,例如),它可以让你更容易地在bison的状态表中向后导航output@SouravKannanthaB:另一件事是,您的注意力集中在
^
的制作上,无论是在您的问题文本中还是在您最初选择的要展示的制作中。但这不是问题所在。问题的关键是触发它的先行标记(或者更可能是一组大的先行标记),因为可能涉及到一个大的缩减链。(这只是一种启发,但至少可以让你找到正确的地方。)