-
Notifications
You must be signed in to change notification settings - Fork 0
/
parser.ypp
241 lines (206 loc) · 12 KB
/
parser.ypp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
%define parse.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 <ExtDefAST *> ExtDefList; //外部定义(外部变量、函数)列表
ExtDefAST *ExtDef;
vector <VarDecAST*> ExtDecList; //外部、局部变量列表
TypeAST *Specifier;
VarDecAST *VarDec;
CompStmAST *CompSt;
vector <ParamAST *> ParamList; //形参列表
ParamAST *ParamDec;
vector <StmAST *> StmList;
StmAST *Stmt;
vector <DefAST *> DefList;
DefAST *Def;
vector <VarDecAST *> DecList;
VarDecAST *Dec;
ExpAST *Exp;
vector <ExpAST *> Args; //实参列表
CaseStmAST *Case;
vector <CaseStmAST *> CaseList;
}YYLVAL;
#define YYSTYPE YYLVAL
%}
// %type 定义非终结符的语义值类型
%type <program> program
%type <ExtDefList> ExtDefList
%type <ExtDef> ExtDef
%type <ExtDecList> ExtDecList
%type <Specifier> Specifier
%type <VarDec> VarDec
%type <VarDec> ParamVarDec
%type <CompSt> CompSt
%type <ParamList> ParamList
%type <ParamDec> ParamDec
%type <DefList> DefList
%type <StmList> StmList
%type <Stmt> Stmt
%type <Def> Def
%type <DecList> DecList
%type <Dec> Dec
%type <Exp> Exp
%type <Exp> Sub
%type <Args> SubList
%type <Case> Case;
%type <CaseList> CaseList
%type <Args> Args
//% token 定义终结符的语义值类型
%token <type_int> INT /*指定INT常量的语义值是type_int,由词法分析得到的整数数值*/
%token <type_id> ID TYPE /*指定ID 的语义值是type_id,由词法分析得到的标识符字符串*/
%token <type_float> 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 <ExtDefAST*>();}
| 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 <StmAST *>(); }
| Stmt StmList {$$=$2;$$.insert($$.begin(),$1);}
;
DefList: {$$=vector <DefAST *>(); }
| 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 <VarDecAST *>(); $$.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 <CaseStmAST *>(); $$.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 <ExpAST *>(); $$.push_back($1); }
| Args COMMA Exp {$$=$1;$$.push_back($3);}
;
Sub: LB Exp RB {$$=$2; }
SubList: Sub {$$=vector <ExpAST *>(); $$.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<stdarg.h>
void yyerror(const char* fmt, ...)
{
Errors::ErrorAdd(yylloc.first_line,yylloc.first_column,fmt);
}