在yacc中%左和右

时间:2012-10-13 20:07:17

标签: gcc compiler-construction syntax if-statement yacc

{%
#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条款的含义...... PLZ在这个场合帮助我......

2 个答案:

答案 0 :(得分:11)

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

%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!

您可以在here中阅读更多内容。

答案 1 :(得分:5)

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

假设我们有语法规则:

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

并假设我们必须解析表达式x + y-z。您可以看到,由于加号和减号的优先级相同,因此该表达式可以解释为(x + y)-z或x +(y-z)。这似乎不是什么大不了的事,但它引入了语法歧义。

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