fengwufeiyang01 2013-12-21 07:15
浏览 1752

ubuntu下bison编写语法分析器的问题

用flex和bison编写语法分析器,但是有一行提示语法错误,涉及到“REALNUM”和“INTEGER”的产生式都会报错,求解答。
测试内容为:
main()
{
int a;
double b;
a=true;
a=false;
}
此时能通过,但是测试内容为
main()
{
int a;
double b;
a=1;
b=1.4;
}
就会报第5行第6行语法错误。求解。
相关代码如下:
flex.l中:
IDENTIFIER[a-zA-Z_$][a-zA-Z0-9_$]*
INTEGER ^-?[0-9]+$
REALNUM ^(-?[0-9]+)(.[0-9]+)?$
…………
{IDENTIFIER} {ids++; yylval.id=(char*)strdup(yytext);
return IDENTIFIER;}
{INTEGER} {ints++; yylval.interval = atoi(yytext);
return INTEGER;}
{REALNUM} {reals++;yylval.realval = atof(yytext);
return REALNUM;}
{WHITESPACE} {}
{NEWLINE} {lineno++;}
syntax.y中
program:
MAIN '(' ')' SBLOCK {printf("(%d)\t program ->MAIN() SBLOCK\n",linenum++);}
;

SBLOCK:
'{' DECLS STMTS '}' {printf("(%d)\t SBLOCK -> { DECLS STMTS }\n",linenum++);}
;

DECLS:
DECLS DECL {printf("(%d)\tDECLS -> DECLS DECL\n",linenum++);}
| {printf("(%d)\tDECLS -> e\n",linenum++);}
;

DECL:
INT IDENTIFIER ';' {printf("(%d)\tDECL -> INT %s\n",linenum++,$2);}
|REAL IDENTIFIER ';' {printf("(%d)\tDECL -> REAL %s\n",linenum++,$2);}
;

STMTS:
STMTS STMT {printf("(%d)\tSTMTS -> STMTS STMT\n",linenum++);}
| {printf("(%d)\tSTMTS -> e\n",linenum++);}
;

STMT:
IDENTIFIER ASSGNOP BEXP ';' {printf("(%d)\t STMT -> %s = BEXP\n",linenum++,$1);}
|IF '(' BEXP ')' STMT %prec IF_THEN {printf("(%d)\t STMT -> IF ( BEXP ) STMT\n",linenum++);}
|IF '(' BEXP ')' STMT ELSE STMT {printf("(%d)\t STMT -> IF ( BEXP ) STMT ELSE STMT\n",linenum++);}
|WHILE '(' BEXP ')' STMT {printf("(%d)\t STMT -> WHILE ( BEXP ) SBLOCK\n",linenum++);}
|DO STMT WHILE '(' BEXP ')' ';' {printf("(%d)\t STMT -> DO SBLOCK WHILE ( BEXP ) ;\n",linenum++);}
;

BEXP:
BEXP OR JOIN {printf("(%d)\tBEXP -> BEXP || JOIN\n",linenum++);}
|JOIN {printf("(%d)\tBEXP -> JOIN \n",linenum++);}
;
JOIN:
JOIN AND EQEXP {printf("(%d)\tJOIN -> JOIN && EQEXP\n",linenum++);}
|EQEXP {printf("(%d)\tJOIN -> EQEXP\n",linenum++);}
;
EQEXP:
EQEXP EQ REL {printf("(%d)\tEQEXP -> EQEXP == REL\n",linenum++);}
|EQEXP NE REL {printf("(%d)\tEQEXP -> EQEXP != REL\n",linenum++);}
|REL {printf("(%d)\tEQEXP -> REL\n",linenum++);}
;
REL:
EXP GT EXP {printf("(%d)\tREL -> EXP > EXP\n",linenum++);}
|EXP LT EXP {printf("(%d)\tREL -> EXP < EXP\n",linenum++);}
|EXP GE EXP {printf("(%d)\tREL -> EXP >= EXP\n",linenum++);}
|EXP LE EXP {printf("(%d)\tREL -> EXP <= EXP\n",linenum++);}
|EXP {printf("(%d)\tREL -> EXP\n",linenum++);}
;
EXP:
EXP '+' TERM {printf("(%d)\tEXP -> EXP + TERM\n",linenum++);}
|EXP '-' TERM {printf("(%d)\tEXP -> EXP - TERM\n",linenum++);}
|TERM {printf("(%d)\tEXP -> TERM\n",linenum++);}
;
TERM:
TERM '*' UNARY {printf("(%d)\tTERM -> TERM * UNARY\n",linenum++);}
|TERM '/' UNARY {printf("(%d)\tTERM -> TERM / UNARY\n",linenum++);}
|UNARY {printf("(%d)\tTERM -> UNARY\n",linenum++);}
;
UNARY:
NOT UNARY {printf("(%d)\tUNARY -> ! UNARY\n",linenum++);}
//|'-' UNARY {printf("(%d)\tUNARY -> - UNARY\n",linenum++);}
|FACTOR {printf("(%d)\tUNARY -> FACTOR\n",linenum++);}
;
FACTOR:
'(' BEXP ')' {printf("(%d)\tFACTOR -> ( BEXP )\n",linenum++);}
|INTEGER {printf("(%d)\tFACTOR -> %d\n",linenum++,$1);}
|REALNUM {printf("(%d)\tFACTOR -> %f\n",linenum++,$1);}
|IDENTIFIER {printf("(%d)\tFACTOR -> %s\n",linenum++,$1);}
|TRUE {printf("(%d)\tFACTOR -> true\n",linenum++);}
|FALSE {printf("(%d)\tFACTOR -> false\n",linenum++);}
;

  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥15 C++ yoloV5改写遇到的问题
    • ¥20 win11修改中文用户名路径
    • ¥15 win2012磁盘空间不足,c盘正常,d盘无法写入
    • ¥15 用土力学知识进行土坡稳定性分析与挡土墙设计
    • ¥70 PlayWright在Java上连接CDP关联本地Chrome启动失败,貌似是Windows端口转发问题
    • ¥15 帮我写一个c++工程
    • ¥30 Eclipse官网打不开,官网首页进不去,显示无法访问此页面,求解决方法
    • ¥15 关于smbclient 库的使用
    • ¥15 微信小程序协议怎么写
    • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?