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

标签 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. 您允许 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 定义不会将 ++ 识别为单个 tomen,unlime,例如 <=。这意味着您的语法会考虑 i++ 成为有效的后增量。也许这是故意的,但它肯定与我所知道的任何语言不同。无论如何,结果将适用 + 的优先级声明,这是不正确的: 3*j++ 应解析为 3*(j++),而不是 (3*j)++。(对于后减运算符。)

关于c - 修复给定代码中的冲突? "25 shift/reduce conflicts [-Wconflicts-sr] ",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40328263/

相关文章:

c - 为什么 "string"在标准C库函数名中缩写为 "a"?

compiler-construction - 查找多语言编译器或优化器(C,C++,Java)

c++ - 为什么不能使用 LEX/YACC 为编译器解析 C++?

c - &((struct name *)NULL -> b) 会导致 C11 中的未定义行为吗?

C 调试,#if DEBUG 与 if (DEBUG)

c - C中的结构体和指针

c - 运行 lex 和 yacc 时出现语法错误

c++ - Qt 有资源系统限制吗?

c - 如何使用 bison + flex 编写计算器

c++ - YACC:无法更改 token 数据类型