linux下的bison报错,求高手指教!急

蜗蜗牛快跑 2013-05-30 02:59:48
想用flex+bison写个简单的编译器,生成三地址中间代码。结果bison的编译就一堆警告。。。大概是说定义的文法没有用之类的。

这个是flex文件

%option noyywrap nodefault yylineno

%{
#include "compiler.h"
#include "parsing.tab.h"
%}

%%
"+" |
"-" |
"*" |
"/" |
"=" |
";" |
"(" |
")" |
"{" |
"}" { return yytext[0];}

">" { yylval.cmp = 1; return CMP; }
"<" { yylval.cmp = 2; return CMP; }
"!=" { yylval.cmp = 3; return CMP; }
"==" { yylval.cmp = 4; return CMP; }
">=" { yylval.cmp = 5; return CMP; }
"<=" { yylval.cmp = 6; return CMP; }

"if" { return IF; }
"else" { return ELSE; }
"while" { return WHILE; }
"do" { return DO; }
"break" { return BREAK;}

"&&" { return AND;}
"||" { return OR;}

"int" { yylval.type=1; return TYPE;}
"float" { yylval.type=2; return TYPE;}
"bool" { yylval.type=3; return TYPE;}

[0-9]+ { yylval.i=atoi(yytext); return INTEGER;}
[0-9]+"."[0-9]* { yylval.d=atof(yytext); return FLOAT;}
"true" |
"false" { yylval.b=strdup(yytext); return BOOLEAN;}

[a-zA-Z][a-zA-Z0-9]* { yylval.s = lookup(yytext); return ID; }

"//".*
[ \t\n]

. { yyerror("error input %c\n",*yytext);}
%%




这个是bison文件,所有的警告都在这里


%{
#include <stdio.h>
#include <stdlib.h>
#include "compiler.h"
%}

%union{
struct ast *a;

double d;
int i;
char * b;

struct symbol *s;

int cmp;
int type;
}


%token <i> INTEGER
%token <d> FLOAT
%token <b> BOOLEAN
%token <s> ID
%token EOL

%token IF ELSE WHILE DO BREAK
%token AND OR

%token <type> TYPE

%nonassoc <cmp> CMP
%right '='
%left '+' '-'
%left '*' '/'

%type <a> block
%type <a> decls decl type
%type <a> stmts stmt loc bool
%type <a> join equality expr term unary factor

%start calclist

%%

block: '{' decls stmts '}' { $$=$3;}
;

decls: decls decl
;
decl: type ID ';'
;
type: type '[' INTEGER ']'
| TYPE { $$=newast('X',S1,NULL);}
;

stmts: stmts stmt { $$=newast('C',$1,$2);}
;
stmt: loc '=' bool ';' { $$=newast('=',$1,$3);}
| IF '(' bool ')' stmt { $$=newflow('I',$3,$5,NULL);}
| IF '(' bool ')' stmt ELSE stmt { $$=newflow('I',$3,$5,$7);}
| WHILE '(' bool ')' stmt { $$=newflow('W',$3,$5,NULL);}
| DO stmt WHILE '(' bool ')' ';' { $$=newflow('D',$5,$2,NULL);}
| BREAK ';' { $$=newast('B',NULL,NULL);}
| block
;

loc: loc '[' bool ']' { $$=newast('[',$1,$3);}
| ID { $$=newref($1);}
;
bool: bool OR join { $$=newast('|',$1,$3);}
| join
;
join: join AND equality { $$=newast('&',$1,$3);}
| equality
;
equality: equality CMP expr { $$=newcmp($2,$1,$3);}
| expr
;
expr: expr '+' term { $$=newast('+',$1,$3);}
| expr '-' term { $$=newast('-',$1,$3);}
| term
;
term: term '*' unary { $$=newast('*',$1,$3);}
| term '/' unary { $$=newast('/',$1,$3);}
| unary
;
unary: '!' unary { $$=newast('!',$2,NULL);}
| '-' unary { $$=newast('M',$2,NULL);}
| factor
;
factor: '(' bool ')' { $$=$2;}
| loc
| INTEGER { $$=newint($1);}
| FLOAT { $$=newflo($1);}
| BOOLEAN { $$=newbol($1);}
;

calclist:
| calclist block EOL { $2;printf("end\n");}
;
%%



警告大概如下:
parsing.y: 警告: 14 nonterminals useless in grammar
parsing.y: 警告: 36 rules useless in grammar
parsing.y:38.11-15: 警告: nonterminal useless in grammar: block
...(省略)
parsing.y:47.8-41: 警告: rule useless in grammar: block: '{' decls stmts '}'
...(省略)

求高手分析上面定义的文法是否不可以用在bison中,还是我哪里写错了。。。
...全文
402 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
蜗蜗牛快跑 2013-05-30
  • 打赏
  • 举报
回复

 状态 63

    8 stmt: IF '(' bool ')' stmt .
    9     | IF '(' bool ')' stmt . ELSE stmt

    ELSE  shift, and go to state 72

    ELSE      [reduce using rule 8 (stmt)]
    $default  reduce using rule 8 (stmt)
不好意思,说错了,二义性仅存在于if else模块
蜗蜗牛快跑 2013-05-30
  • 打赏
  • 举报
回复

stmt: loc '=' bool ';'                { $$=newast('=',$1,$3);}
    | IF '(' bool ')' stmt             { $$=newflow('I',$3,$5,NULL);}
    | IF '(' bool ')' stmt ELSE stmt    { $$=newflow('I',$3,$5,$7);}   
    | WHILE '(' bool ')' stmt        { $$=newflow('W',$3,$5,NULL);}
    | DO stmt WHILE '(' bool ')' ';'    { $$=newflow('D',$5,$2,NULL);}
    | BREAK ';'                { $$=newast('B',NULL,NULL);}
    | block 
;
二义性问题出现在if else 和while 模块。。。有这方面解决经验的高手,不吝赐教呀~~~
蜗蜗牛快跑 2013-05-30
  • 打赏
  • 举报
回复
恩,正在尝试。好像已经找到问题所在了。。。貌似是以下两句导致的 decls: decls decl stmts: stmts stmt { $$=newast('C',$1,$2);} 改为: decls: decls decl | decl stmts: stmts stmt { $$=newast('C',$1,$2);} | stmt 虽然解决了无效文法的问题,但是接着二义性的问题又出现了。。。
那闯 2013-05-30
  • 打赏
  • 举报
回复
警告说的很清楚了, block: '{' decls stmts '}' 这个语法没有用到, 没有终结符
赵4老师 2013-05-30
  • 打赏
  • 举报
回复
偶遇到类似问题都是用 “每次用/*...*/注释掉不同部分再重新编译,直到定位到具体语法出错的位置。” 的方法解决的。
蜗蜗牛快跑 2013-05-30
  • 打赏
  • 举报
回复
顺便说下,该文法来自于龙书背后的编译器前端。

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧