修复给定代码中的冲突? “25 shift/reduce 冲突 [-Wconflicts-sr]”

Fixing conflict in given code? "25 shift/reduce conflicts [-Wconflicts-sr] "

// Lex 文件:for.l

alpha [A-Za-z]  
digit [0-9]  
%%  
[\t \n]   
for         return FOR;  
{digit}+    return NUM;  
{alpha}({alpha}|{digit})* return ID;  
"<="         return LE;  
">="         return GE;  
"=="         return EQ;  
"!="          return NE;  
"||"          return OR;  
"&&"         return AND;  
.            return yytext[0];  
%% 

// Yacc 文件: for.y

%{  
#include<stdio.h>  
#include<stdlib.h>  
%}  
%token ID NUM FOR LE GE EQ NE OR AND  
%right "="  
%left OR AND  
%left '>' '<' LE GE EQ NE  
%left '+' '-'  
%left '*' '/'  
%right UMINUS  
%left '!'  
%%  
S         : ST {printf("Input accepted\n"); exit(0);}  
ST       : FOR '(' E ';' E2 ';' E ')' DEF  
;  
DEF    : '{' BODY '}'  
| E';'   
| ST  
|  
;   
BODY  : BODY BODY  
| E ';'          
| ST  
|               
;  
E     : ID '=' E   
| E '+' E   
| E '-' E  
| E '*' E  
| E '/' E  
| E '<' E  
| E '>' E  
| E LE E  
| E GE E  
| E EQ E  
| E NE E  
| E OR E  
| E AND E  
| E '+' '+'   
| E '-' '-'  
| ID    
| NUM  
;
E2     : E'<'E  
| E'>'E  
| E LE E  
| E GE E  
| E EQ E  
| E NE E  
| E OR E  
| E AND E  
;      
%%  
#include "lex.yy.c"  
main() 
{  
printf("Enter the expression:\n");  
yyparse();  
}        

当我运行它时,它显示:

warning: 25 shift/reduce conflicts [-Wconflicts-sr]  
warning: 4 reduce/reduce conflicts [-Wconflicts-rr]  

我该如何解决?

编译方法:

$ lex c.l  
$ yacc c.y  

你的语法有很多问题;这是最明显的:

  1. 您允许 DEF 为空。也就是说

     for (i=0;i<1;i++)  for (j=0;j<1;j++) 
    

    可以是两个 for 具有空主体的语句,或者一个 for 语句,其主体是另一个 for 语句(其主体为空)。所以空产生式使语法有歧义。

  2. BODY: BODY BODY 是指数级的歧义,没有优先级声明可以弥补。由于 BODY.

  3. 有一个(也是不必要的)空生产这一事实使问题变得更糟
  4. E '+' '+' 暗示 i++ 中的两个 + 是单独的标记(事实上,您的 flex 定义没有将 ++ 识别为单个 tomen,unlime,例如 <=。这意味着您的语法会认为 i + + 是一个有效的 post 增量。也许那是故意的,但它肯定不同于我所知道的任何语言。无论如何,结果会证明 + 的优先级声明将适用,这是不正确的:3*j++ 应该被解析为 3*(j++),而不是 (3*j)++。(post-递减运算符也是如此。)