{%
#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在这个场合帮助我......
答案 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()
这样的表达式。