Bison 本野牛代码中的移位/减少冲突在哪里?

Bison 本野牛代码中的移位/减少冲突在哪里?,bison,shift-reduce-conflict,Bison,Shift Reduce Conflict,我的野牛代码中有一个大便/减少冲突: expression : LBRACKET expression RBRACKET {$$ = $2;} | fct_call {} | operand {} | expression operator_arith expression {$$ = new NBinaryOperation(*$1, $

我的野牛代码中有一个大便/减少冲突:

expression : LBRACKET expression RBRACKET  {$$ = $2;}
       | fct_call                          {}
       | operand                           {}    
       | expression operator_arith expression   {$$ = new NBinaryOperation(*$1, $2, *$3);}
       ;
我可以通过写作来解决这个问题:

expression : LBRACKET expression RBRACKET compexp  // {$$ = $2;}
       | fct_call_in_exp compexp               {}
       | operand compexp                       {}
       ;
compexp : /* empty */     {/* Do smthg */}
    | operator_arith expression   {/* Do smthg */}
但是我的节点结构需要做很多修改。因此,我正在寻找一种新的方法来解决它。 你能帮我吗

祝你有愉快的一天

这是不明确的:

expression : expression operator_arith expression
问题是,如果有多个中缀运算符(例如,
A+B*C
),则可以首先使用左运算符(远离解析树的根)或右运算符对其进行解析

您需要决定如何解决这种歧义,并将其添加到解析器中。通常的方法是定义优先级别,即某些运算符的优先级高于其他运算符(因此应始终首先解析它们),对于相同级别的运算符,左运算符或右运算符应位于第一位(通常称为左递归和右递归)

有两种方法可以消除歧义。您可以引入更多的非终结符(每个优先级别一个),并使用它们编写语法(有许多示例语法使用
术语
因子
以及这些额外级别的其他相关内容)。或者,您可以使用bison内置的
%left
%right
声明来设置各种运算符标记的优先级,并为每个生产赋予匹配的优先级(通过直接使用标记或使用
%prec
)。每个优先级(至少)需要一个单独的产品,以便为它们提供不同的优先级

野牛的手册中有后一种风格的例子