Parsing 具有2个以上递归的运算符优先级

Parsing 具有2个以上递归的运算符优先级,parsing,bison,operator-precedence,Parsing,Bison,Operator Precedence,我正在尝试一些关于bison的操作符优先级和结合性的组合。虽然在某些情况下这看起来很奇怪,但基本的问题是,如果下面的规则是有效的,那么看起来并没有错 expr: expr OP1 expr OP5 '+' expr 根据bison信息页面,规则优先于最后一个终端符号或明确指定给它的优先级。 以下是代码中的优先和完整expr规则粘贴: %left OP4 %left OP3 %left OP2 %left OP1 %left '*' %left '/' %left '+' %left '-'

我正在尝试一些关于bison的操作符优先级和结合性的组合。虽然在某些情况下这看起来很奇怪,但基本的问题是,如果下面的规则是有效的,那么看起来并没有错

expr: expr OP1 expr OP5 '+' expr
根据bison信息页面,规则优先于最后一个终端符号或明确指定给它的优先级。 以下是代码中的优先和完整expr规则粘贴:

%left OP4
%left OP3
%left OP2
%left OP1
%left '*'
%left '/'
%left '+'
%left '-'

expr:  NUM                               { $$ = $1; }
| expr OP2 expr OP5 '+' expr             { printf("+"); }
| expr OP1 expr OP5 '-' expr             { printf("-"); }
| expr OP4 expr OP5 '*' expr             { printf("*"); }
| expr OP3 expr OP5 '/' expr             { printf("/"); }
          ;
Below is data tokens given:
1op11op5-2op22op5+3op33op5/4op44op5*5
执行解析器时的输出低于预期

-+/*
现在,一旦在算术运算符和OP之间翻转优先级,结果就会反转,表明不是最后一个端子影响规则优先级

%left '*'
%left '/'
%left '+'
%left '-'
%left OP4
%left OP3
%left OP2
%left OP1
现在,解析器的输出是反向的,这表明最后一个终端顺序没有帮助:

*/-+
此外,若第一次组合中只有算术运算符的优先级高于OP运算符,若移除OP运算符的优先级,则结果仍然是第二次组合,且无规则播放。这一结果使得很难得出结论,第二个表达式用于预测,而不是第三个表达式。 从以上结果可以得出什么结论。
如果规则中使用了两个以上的递归,那么优先级和关联性逻辑会是什么呢?

bison中的“Precence”规则实际上与传统意义上的运算符优先级没有太多关系——它们实际上只是一种解决移位-减少冲突的方法,可以以一种简单的方式实现运算符优先级模棱两可的语法。因此,要了解它们是如何工作的,您需要了解shift/reduce解析以及如何使用优先级规则来解决冲突

实际的机制其实很简单。每当bison在为语法生成的解析器中出现移位/减少冲突时,它都会查看冲突中涉及的规则(to reduce)和标记(to shift),如果两者都指定了优先级,它会以优先级较高的规则(to reduce)和标记(to shift)解决冲突。就这样


因此,这对于解决简单二进制运算符的优先级问题非常有效,但如果您试图将其用于更复杂的问题,则可能会给您带来麻烦。在您的示例中,冲突都发生在OP1/2/3/4的规则和移位之间,因此重要的是这两个组的相对优先级——每个组内的优先级都是无关的,因为它们之间从来没有任何冲突。因此,当规则具有更高的优先级时,它们将从左向右减少,而当OP标记具有更高的优先级时,它将移动(最终导致从右向左减少).

bison中的“precence”规则实际上与传统意义上的运算符优先级没有太大关系——它们实际上只是一种解决移位-减少冲突的方法,可以在模糊语法中实现简单的运算符优先级。因此,要了解它们是如何工作的,您需要了解shift/reduce解析以及如何使用优先级规则来解决冲突

实际的机制其实很简单。每当bison在为语法生成的解析器中出现移位/减少冲突时,它都会查看冲突中涉及的规则(to reduce)和标记(to shift),如果两者都指定了优先级,它会以优先级较高的规则(to reduce)和标记(to shift)解决冲突。就这样


因此,这对于解决简单二进制运算符的优先级问题非常有效,但如果您试图将其用于更复杂的问题,则可能会给您带来麻烦。在您的示例中,冲突都发生在OP1/2/3/4的规则和移位之间,因此重要的是这两个组的相对优先级——每个组内的优先级都是无关的,因为它们之间从来没有任何冲突。因此,当规则具有更高的优先级时,它们将从左向右减少,而当OP标记具有更高的优先级时,它将移动(最终导致从右向左减少)。

这是否意味着运算符优先级仅对中缀算术语法等语法有效?在我的例子中,由于右递归,它实际上一直移动到末尾,而当算术运算符具有更高的优先级时,它会减少。对于复杂的递归规则,除了运算符优先级之外,还有其他选择吗?这是否意味着运算符优先级仅对中缀算术语法之类的语法有效?在我的例子中,由于右递归,它实际上一直移动到末尾,而当算术运算符具有更高的优先级时,它会减少。对于复杂的递归规则,除了运算符优先级之外,还有其他选择吗?