69,371
社区成员
发帖
与我相关
我的任务
分享
%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);}
%%
%{
#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");}
;
%%
状态 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模块
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 模块。。。有这方面解决经验的高手,不吝赐教呀~~~