15
{%
#include<stdio.h>
#include<stdlib.h>
%}
  
%token ID NUM IF THEN LE GE EQ NE OR AND ELSE

%right '='
%left AND OR
%left '<' '>' LE GE EQ NE
%left '+''-'
%left '*''/'
%right UMINUS
%left '!'

%%

上面提到的代码是一个简单IF ELSE程序的 yacc 的一部分。

是什么%right意思%left

4

2 回答 2

23

我知道这是一个老问题,但万一其他人正在寻找此信息:

%left,%right%nonassoc, 定义 yacc 将如何解决运算符的重复问题。如果您有:

1 + 2 + 3

两个运算符具有相同的优先级(它们是相同的:)),在这种情况下 yacc 可以解决:

// using %left
(1 + 2) + 3

或者:

// using %right
1 + (2 + 3)

最后:

//using %nonassoc
1 + 2 + 3 is considered illegal and a syntax error!

你可以在这里阅读更多。

于 2016-01-11T01:13:05.260 回答
11

%left%right指定运算符的关联性。操作的关联性决定了相同优先级的两个操作中的哪一个先执行。

假设我们有语法规则:

exp ::= exp + exp
exp ::= ID

假设我们必须解析表达式 x+yz。你看,由于加减的优先级是一样的,这个表达式可以解释为(x+y)-z或者x+(yz)。这似乎没什么大不了的,但它在语法中引入了歧义。

除了解析问题和理论,假设我们正在解析表达式。6+5-7,并假设我们的语言只能处理自然数,并且在发生下溢时抛出异常。(4)的结果(6+5)-7将不等于6+(5-7)(exception),因此我们将无法预测结果——除非我们通过指定运算符的关联性来定义评估顺序。还要考虑表达式的情况,例如f()+g()+h(),当操作数是可能有副作用的函数时。

于 2012-10-14T10:36:07.997 回答