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

时间:2016-10-30 10:46:14

标签: c compiler-construction bison flex-lexer

// 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 个答案:

答案 0 :(得分:1)

你的语法有各种各样的问题;这是最明显的:

  1. 您允许DEF为空。这意味着

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

    可以是两个带有空体的for语句,或一个for语句,其主体是另一个for语句(其主体为空)。所以空白的制作会使语法模糊不清。

  2. BODY: BODY BODY呈指数式模糊,没有优先级声明可以补偿。由于BODY有(也是不必要的)空制作,这个问题会变得更糟。

  3. E '+' '+'表示i++中的两个 + 是单独的标记(实际上,您的flex定义无法识别 ++ < / kbd>作为单个tomen,unlime,例如,&lt; = 。这意味着你的语法会认为i + +是一个有效的后增量。也许这是有意的,但是它肯定不同于我所知道的任何语言。无论如何,事实证明 + 的优先声明将适用,这是不正确的:3*j++应解析为3*(j++),不是(3*j)++。(对于后递减运算符也是如此。)