//%define parse.error verbose %error-verbose %locations %{ #include "def.h" extern int ErrorCharNum; extern int yylineno; extern char *yytext; extern FILE *yyin; void yyerror(const char* fmt, ...); extern "C" int yylex(); #define SavePosition t->Line=yylloc.first_line;t->Column=yylloc.first_column typedef struct YYLVAL { int type_int; float type_float; char type_id[32]; ProgAST *program; vector ExtDefList; //外部定义(外部变量、函数)列表 ExtDefAST *ExtDef; vector ExtDecList; //外部、局部变量列表 TypeAST *Specifier; VarDecAST *VarDec; CompStmAST *CompSt; vector ParamList; //形参列表 ParamAST *ParamDec; vector StmList; StmAST *Stmt; vector DefList; DefAST *Def; vector DecList; VarDecAST *Dec; ExpAST *Exp; vector Args; //实参列表 CaseStmAST *Case; vector CaseList; }YYLVAL; #define YYSTYPE YYLVAL %} // %type 定义非终结符的语义值类型 %type program %type ExtDefList %type ExtDef %type ExtDecList %type Specifier %type VarDec %type ParamVarDec %type CompSt %type ParamList %type ParamDec %type DefList %type StmList %type Stmt %type Def %type DecList %type Dec %type Exp %type Sub %type SubList %type Case; %type CaseList %type Args //% token 定义终结符的语义值类型 %token INT /*指定INT常量的语义值是type_int,由词法分析得到的整数数值*/ %token ID TYPE /*指定ID 的语义值是type_id,由词法分析得到的标识符字符串*/ %token FLOAT /*指定float常量的语义值是type_float*/ %token DPLUS DMINUS PLUSD MINUSD LP RP LB RB LC RC SEMI COMMA /*用bison对该文件编译时,带参数-d,生成的exp.tab.h中给这些单词进行编码,可在lex.l中包含parser.tab.h使用这些单词种类码*/ %token PLUS MINUS STAR DIV MOD GE GT LE LT NE EQ ASSIGN AND OR NOT IF ELSE WHILE RETURN FOR %token BREAK CONTINUE SWITCH CASE DEFAULT COLON /*以下为接在上述token后依次编码的枚举常量,用于后续过程*/ %token ARRPRO EXT_DEF_LIST EXT_VAR_DEF FUNC_DEF FUNC_DEC EXT_DEC_LIST PARAM_LIST PARAM_DEC VAR_DEF DEC_LIST DEF_LIST COMP_STM STM_LIST EXP_STMT IF_THEN IF_THEN_ELSE %token FUNC_CALL ARGS FUNCTION PARAM ARG CALL CALL0 LABEL GOTO JLT JLE JGT JGE JEQ JNE END ARRASSIGN ARRLOAD ARRDPLUS ARRDMINUS ARRPLUSD ARRMINUSD %left COMMA %left ASSIGN %left OR %left AND %left LT LE GT GE %left NE EQ %left MOD %left PLUS MINUS %left STAR DIV %right UMINUS NOT DPLUS DMINUS UPLUS %left PLUSD MINUSD %left ARRPRO %nonassoc LOWER_THEN_ELSE %nonassoc ELSE %% program: ExtDefList {$$=new ProgAST(); $$->ExtDefs=$1; if (Errors::IsEmpty() && ErrorCharNum==0) { $$->DisplayAST(0); } //无词法、语法错误显示语法树 else {Errors::ErrorsDisplay();return 0;} $$->Semantics0(); //静态语义检查 if (Errors::IsEmpty()) $$->GenIR(); //中间代码生成 exit(0); } ; ExtDefList: {$$=vector ();} | ExtDef ExtDefList {$2.insert($2.begin(),$1);$$=$2;} //将ExtDef所指外部定义对象增加到(程序对象的)ExtDefList中 ; ExtDef: Specifier ExtDecList SEMI { ExtVarDefAST *t=new ExtVarDefAST(); //创建一个外部变量声明的对象 t->Type=$1; t->ExtVars=$2; $$=t; SavePosition;} | Specifier ID LP ParamList RP CompSt {FuncDefAST *t=new FuncDefAST();t->Type=$1;t->Name=$2;t->Params=$4; t->Body=$6;$$=t;SavePosition;}//对应一个函数定义对象 | Specifier ID LP ParamList RP SEMI {FuncDefAST *t=new FuncDefAST();t->Type=$1;t->Name=$2;t->Params=$4;$$=t;SavePosition;}//对应一个函数声明对象,Body为空 ; Specifier: TYPE { BasicTypeAST *t=new BasicTypeAST(); ; if (string($1)==string("int")) t->Type=T_INT; if (string($1)==string("float")) t->Type=T_FLOAT; if (string($1)==string("void")) t->Type=T_VOID; $$=t;SavePosition;} ; ExtDecList: VarDec {$$=vector < VarDecAST*>();$$.push_back($1);} /*ExtDecList对应一个外部变量VarDec的序列,目前后续只考虑是标识符,可扩展为数组*/ | VarDec COMMA ExtDecList {$3.insert($3.begin(),$1);$$=$3;} ; VarDec: ID {VarDecAST *t=new VarDecAST(); t->Name=string($1); $$=t; SavePosition;} //变量对象,dims.size()为0表示简单变量,大于0表示数组 | VarDec LB INT RB {$1->Dims.push_back($3);$$=$1;} //将数组的每维大小添加到属性Dims中 ; ParamVarDec:ID {VarDecAST *t=new VarDecAST(); t->Name=string($1); $$=t; SavePosition;} //变量对象,dims.size()为0表示简单变量,大于0表示数组 ; ParamList: {$$=vector < ParamAST *>();} | ParamDec {$$=vector < ParamAST *>(); $$.push_back($1); } //初始化形式参数序列 | ParamList COMMA ParamDec {$1.push_back($3); $$=$1;} //添加一个形式参数 ; ParamDec: Specifier ParamVarDec {ParamAST* t=new ParamAST();t->Type=$1;t->ParamName=$2; $$=t; SavePosition;} ; CompSt: LC DefList StmList RC {CompStmAST *t=new CompStmAST();t->Decls=$2;t->Stms=$3;$$=t;SavePosition;} ; StmList: {$$=vector (); } | Stmt StmList {$$=$2;$$.insert($$.begin(),$1);} ; DefList: {$$=vector (); } | Def DefList {$$=$2;$$.insert($$.begin(),$1);} ; Def: Specifier DecList SEMI {DefAST *t=new DefAST();t->Type=$1;t->LocVars=$2;$$=t;SavePosition;} ; DecList: Dec {$$=vector (); $$.push_back($1);} | Dec COMMA DecList {$$=$3;$$.insert($$.begin(),$1);} ; Dec: VarDec {$$=$1;} //如何将多种形式的局部变量加上一个父类,简单,数组,初始化 | VarDec ASSIGN Exp {$$=$1;$$->Exp=$3; } //带初始化的变量定义 ; Case: CASE Exp COLON StmList {CaseStmAST *t=new CaseStmAST(); t->Cond=$2; t->Body=$4; $$=t; SavePosition;} CaseList:Case {$$=vector (); $$.push_back($1); } | Case CaseList {$$=$2; $$.insert($$.begin(),$1); } Stmt: Exp SEMI {ExprStmAST *t=new ExprStmAST();t->Exp=$1;$$=t;SavePosition;} | CompSt {$$=$1;} //复合语句不再生成新的结点 | RETURN Exp SEMI {ReturnStmAST *t=new ReturnStmAST();t->Exp=$2;$$=t;SavePosition;} | RETURN SEMI {ReturnStmAST *t=new ReturnStmAST();t->Exp=NULL;$$=t;SavePosition;} | IF LP Exp RP Stmt %prec LOWER_THEN_ELSE {IfStmAST *t=new IfStmAST();t->Cond=$3;t->ThenStm=$5;$$=t; SavePosition;} | IF LP Exp RP Stmt ELSE Stmt {IfElseStmAST *t=new IfElseStmAST();t->Cond=$3;t->ThenStm=$5;t->ElseStm=$7;$$=t;SavePosition;} | WHILE LP Exp RP Stmt {WhileStmAST *t=new WhileStmAST();t->Cond=$3;t->Body=$5; $$=t; SavePosition; } | FOR LP Exp SEMI Exp SEMI Exp RP Stmt {ForStmAST *t=new ForStmAST(); t->SinExp=$3; t->Cond=$5; t->EndExp=$7; t->Body=$9; $$=t; SavePosition;} | SWITCH LP Exp RP LC CaseList RC {SwitchStmAST *t=new SwitchStmAST(); t->Exp=$3; t->Cases=$6; t->containDefault=0; $$=t; SavePosition;} | SWITCH LP Exp RP LC CaseList DEFAULT COLON StmList RC {SwitchStmAST *t=new SwitchStmAST(); t->Exp=$3; t->Cases=$6; t->containDefault=1; t->Default=$9; $$=t; SavePosition;} | BREAK SEMI {BreakStmAST *t=new BreakStmAST(); $$=t; SavePosition; } | CONTINUE SEMI {ContinueStmAST *t=new ContinueStmAST(); $$=t; SavePosition; } | error SEMI {$$=NULL;} ; Exp: Exp ASSIGN Exp {AssignAST *t=new AssignAST();t->Op=ASSIGN; t->LeftValExp=$1;t->RightValExp=$3;$$=t;SavePosition;} | Exp PLUS Exp {BinaryExprAST *t=new BinaryExprAST();t->Op=PLUS;t->LeftExp=$1;t->RightExp=$3;$$=t;SavePosition;} //算术运算符 | Exp MINUS Exp{BinaryExprAST *t=new BinaryExprAST();t->Op=MINUS;t->LeftExp=$1;t->RightExp=$3;$$=t;SavePosition;} | Exp STAR Exp {BinaryExprAST *t=new BinaryExprAST();t->Op=STAR;t->LeftExp=$1;t->RightExp=$3;$$=t;SavePosition;} | Exp DIV Exp {BinaryExprAST *t=new BinaryExprAST();t->Op=DIV;t->LeftExp=$1;t->RightExp=$3;$$=t;SavePosition;} | Exp MOD Exp {BinaryExprAST *t=new BinaryExprAST();t->Op=MOD;t->LeftExp=$1;t->RightExp=$3;$$=t;SavePosition;} | LP Exp RP {$$=$2;} | MINUS Exp %prec UMINUS {UnaryExprAST *t=new UnaryExprAST();t->Op=UMINUS;t->Exp=$2;$$=t;SavePosition;} //单目减 | PLUS Exp %prec UPLUS {UnaryExprAST *t=new UnaryExprAST();t->Op=UPLUS;t->Exp=$2;$$=t;SavePosition;} //单目加 | Exp AND Exp {BinaryExprAST *t=new BinaryExprAST();t->Op=AND;t->LeftExp=$1;t->RightExp=$3;$$=t;SavePosition;} //逻辑运算符 | Exp OR Exp {BinaryExprAST *t=new BinaryExprAST();t->Op=OR;t->LeftExp=$1;t->RightExp=$3;$$=t;SavePosition;} | NOT Exp {UnaryExprAST *t=new UnaryExprAST();t->Op=NOT;t->Exp=$2;$$=t;SavePosition;} | Exp GT Exp {BinaryExprAST *t=new BinaryExprAST();t->Op=GT;t->LeftExp=$1;t->RightExp=$3;$$=t;SavePosition;} //关系运算符 | Exp GE Exp {BinaryExprAST *t=new BinaryExprAST();t->Op=GE;t->LeftExp=$1;t->RightExp=$3;$$=t;SavePosition;} | Exp LT Exp {BinaryExprAST *t=new BinaryExprAST();t->Op=LT;t->LeftExp=$1;t->RightExp=$3;$$=t;SavePosition;} | Exp LE Exp {BinaryExprAST *t=new BinaryExprAST();t->Op=LE;t->LeftExp=$1;t->RightExp=$3;$$=t;SavePosition;} | Exp NE Exp {BinaryExprAST *t=new BinaryExprAST();t->Op=NE;t->LeftExp=$1;t->RightExp=$3;$$=t;SavePosition;} | Exp EQ Exp {BinaryExprAST *t=new BinaryExprAST();t->Op=EQ;t->LeftExp=$1;t->RightExp=$3;$$=t;SavePosition;} | DPLUS Exp {UnaryExprAST *t=new UnaryExprAST();t->Op=DPLUS;t->Exp=$2;$$=t;SavePosition;} //自增、自减运算符。。。可区分前后缀形式 | DMINUS Exp {UnaryExprAST *t=new UnaryExprAST();t->Op=DMINUS;t->Exp=$2;$$=t;SavePosition;} | Exp DPLUS {UnaryExprAST *t=new UnaryExprAST();t->Op=PLUSD;t->Exp=$1;$$=t;SavePosition;} | Exp DMINUS {UnaryExprAST *t=new UnaryExprAST();t->Op=MINUSD;t->Exp=$1;$$=t;SavePosition;} | ID LP Args RP %prec ARRPRO {FuncCallAST *t=new FuncCallAST();t->Name=$1;t->Params=$3;$$=t;SavePosition;} | ID {VarAST *t=new VarAST();t->Name=$1;$$=t;SavePosition;} | ID SubList {VarAST *t=new VarAST();t->Name=$1;t->index=$2;$$=t;SavePosition;} | INT {ConstAST *t=new ConstAST();t->Type=T_INT;t->ConstVal.constINT=$1;$$=t;SavePosition;} | FLOAT {ConstAST *t=new ConstAST();t->Type=T_FLOAT;t->ConstVal.constFLOAT=$1;$$=t;SavePosition;} ; Args: {} | Exp {$$=vector (); $$.push_back($1); } | Args COMMA Exp {$$=$1;$$.push_back($3);} ; Sub: LB Exp RB {$$=$2; } SubList: Sub {$$=vector (); $$.push_back($1); } | SubList Sub {$$=$1; $$.push_back($2);} %% int main(int argc, char *argv[]){ yyin=fopen(argv[1],"r"); if (!yyin) return 0; yylineno=1; yyparse(); return 0; } #include void yyerror(const char* fmt, ...) { Errors::ErrorAdd(yylloc.first_line,yylloc.first_column,fmt); }