我是yacc的新手,并不真正了解如何编写规则,尤其是处理递归定义。
%token NUMBER
%token VARIABLE
%left '+' '-'
%left '*' '/' '%'
%left '(' ')'
%%
S: VARIABLE'='E {
printf("nEntered arithmetic expression is Validnn");
return 0;
}
E : E'+'E
| E'-'E
| E'*'E
| E'/'E
| E'%'E
| '('E')'
| NUMBER
| VARIABLE
;
%%
上面的例子很好,但当我把它改成下面的时候,它得到了">5移位/减少冲突";。
%token NUMBER
%token VARIABLE
%token MINS
%token PULS
%token MUL
%token DIV
%token MOD
%token LP
%token RP
%left MINS PULS
%left MUL DIV MOD
%left LP RP
%%
S: VARIABLE'='E {
printf("nEntered arithmetic expression is Validnn");
return 0;
}
E : E operator E
| LP E RP
| NUMBER
| VARIABLE
;
operator: MINS
| PULS
| MUL
| DIV
| MOD
;
%%
有人能告诉我这些例子之间有什么区别吗?非常感谢。。
区别在于与非终端operator
的附加间接性。这有助于挫败你的优先声明。
先例是直接的,不是透明的。也就是说,它只在包括终端在内的直接生产中发挥作用。在你的第二个语法中,这个结果是:
operator: MINS
| PULS
| MUL
| DIV
| MOD
;
但在这部作品中,没有任何歧义需要解决。所有这些终端都被明确地简化为CCD_ 2。模糊性在生产中
E : E operator E
而且这种生产没有终端。
相比之下,在你的第一个语法中,生成
E : E'+'E
| E'-'E
| E'*'E
| E'/'E
| E'%'E
(如果有更多的空白,则更容易阅读(确实包括可以相互比较其先验的终端。
Bison手册中解释了优先级声明的精确工作。如果有用的话,下面是我几年前在这个网站上的另一个答案中写的算法的描述。