-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathparse.y
More file actions
190 lines (157 loc) · 10.6 KB
/
parse.y
File metadata and controls
190 lines (157 loc) · 10.6 KB
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
/*
* @Copyright: minic
* @Author: David.Huangjunlang
* @Description: Yacc 文件,包含 token 定义,以及规则移进规约定义,以及解析错误时输出错误信息
* @LastEditors: David.Huangjunlang
* @LastEditTime: 2020-04-30 09:30:51
* @FilePath: /minic/parse.y
*/
%{
#include "main.h"
#include "utils.h"
extern node* programNode;
extern FILE* result;
extern int yylineno;
extern char* yytext;
extern int yylex(void);
extern "C"{
void yyerror(const char *s);
int yywrap(void);
}
%}
%token <m_id> ID
%token <m_num> NUM
%token <m_op> PLUS MINUS MULTI DIVIDE
%token <m_op> LESS LESSEQUAL GREATER GREATEREQUAL EQUAL UNEQUAL
%token <m_op> ASSIGNMENT SEMICOLON COMMA
%token <m_op> LEFTBRACKET RIGHTBRACKET LEFTSQUAREBRACKET RIGHTSQUAREBRACKET LEFTBRACE RIGHTBRACE
%token <m_reserved> ELSE IF INT VOID RETURN WHILE
%type <m_node> declaration fun_declaration var_declaration param expression simple_expression additive_expression var term factor call program
%type <m_node> expression_stmt compound_stmt statement selection_stmt iteration_stmt return_stmt
%type <m_node> params local_declarations args
%type <m_node> statement_list param_list declaration_list
%%
program : declaration_list {$$ = newStmtNode(ProgramK); $$->nodeChild[0] = $1;programNode = $$; programNode->name = "helloworld";$$->lineno = yylineno;}
;
declaration_list : declaration_list declaration {addNode($1, $2);$$ = $1;$$->lineno = yylineno; $1->isGlobal = 1;
if($2->kind.stmt != 6){$$->local_size += $2->local_size;}}
| declaration {$$ = newStmtNode(DeclK); addNode($$, $1);$$->lineno = yylineno; $1->isGlobal = 1;if($1->kind.stmt != 6){$$->local_size = $1->local_size;}}
;
declaration : var_declaration SEMICOLON{$$ = $1;$$->lineno = yylineno; $$->local_size = $1->local_size;}
| fun_declaration {$$ = $1;$$->lineno = yylineno;}
;
var_declaration : INT ID {$$ = newStmtNode(VarK); $$->name = $2;$$->lineno = yylineno;$$->local_size = 1;}
| INT ID LEFTSQUAREBRACKET NUM RIGHTSQUAREBRACKET {node *t = newExpNode(ConstK); t->val = $4;
$$ = newStmtNode(ArrayK);$$->name = $2;$$->nodeChild[0] = t;
$$->lineno = yylineno; $$->isArray = 1; $$->local_size=$4;
$$->val = $4;}
;
fun_declaration : VOID ID LEFTBRACKET params RIGHTBRACKET compound_stmt{$$ = newStmtNode(FunK);$$->lineno = yylineno;
$$->type = 0;
$$->name = $2; $$->nodeChild[0] = $4;
if($4 != nullptr){$$->param_size = $4->param_size;};
$$->local_size = $6->local_size;
$$->nodeChild[1] = $6;}
| INT ID LEFTBRACKET params RIGHTBRACKET compound_stmt{$$ = newStmtNode(FunK);$$->lineno = yylineno;
$$->type = 1;
$$->name = $2; $$->nodeChild[0] = $4;
if($4 != nullptr){$$->param_size = $4->param_size;};
$$->local_size = $6->local_size;
$$->nodeChild[1] = $6;}
;
params : param_list {$$ = $1;$$->lineno = yylineno;}
| VOID {$$ = nullptr;}
;
param_list : param_list COMMA param {addNode($1, $3); $$ = $1; $$->param_size += 1;}
| param {$$ = newStmtNode(ParamlK); $$->param_size += 1;addNode($$, $1);$$->lineno = yylineno;}
;
param : INT ID {$$ = newExpNode(IdK); $$->name = $2;$$->lineno = yylineno;$$->isParameter = 1;}
| INT ID LEFTSQUAREBRACKET RIGHTSQUAREBRACKET {$$ = newStmtNode(ArrayK); $$->name = $2;
$$->lineno = yylineno;$$->isParameter = 1; $$->isArray = 1;}
;
compound_stmt : LEFTBRACE local_declarations statement_list RIGHTBRACE {$$ = newStmtNode(CompK);$$->lineno = yylineno;
$$->local_size = $2->local_size + $3->local_size;
$$->nodeChild[0] = $2;
$$->nodeChild[1] = $3;}
| LEFTBRACE local_declarations RIGHTBRACE {$$ = newStmtNode(CompK); $$->nodeChild[0] = $2;
$$->local_size = $2->local_size;
$$->lineno = yylineno;}
| LEFTBRACE statement_list RIGHTBRACE {$$ = newStmtNode(CompK); $$->nodeChild[1] = $2;
$$->local_size = $2->local_size;
$$->lineno = yylineno;}
;
local_declarations : local_declarations var_declaration SEMICOLON {addNode($1, $2); $$ = $1;$$->lineno = yylineno; $$->local_size += $2->local_size;}
| var_declaration COMMA {$$ = newStmtNode(LocdeclK); addNode($$, $1);$$->lineno = yylineno; $$->local_size = $1->local_size;}
| var_declaration SEMICOLON {$$ = newStmtNode(LocdeclK); addNode($$, $1);$$->lineno = yylineno;$$->local_size = $1->local_size;}
| {}
;
statement_list : statement_list statement {addNode($1, $2); $$ = $1;$$->lineno = yylineno;$$->local_size += $2->local_size;}
| statement {$$ = newStmtNode(StmtlK); addNode($$, $1);$$->lineno = yylineno;$$->local_size = $1->local_size;}
;
statement : expression_stmt {$$ = $1;$$->lineno = yylineno;}
| selection_stmt {$$ = $1;$$->lineno = yylineno;}
| compound_stmt {$$ = $1;$$->lineno = yylineno;}
| iteration_stmt {$$ = $1;$$->lineno = yylineno;}
| return_stmt {$$ = $1;$$->lineno = yylineno;}
;
expression_stmt: expression SEMICOLON {$$ = $1;$$->lineno = yylineno;}
| SEMICOLON {}
;
selection_stmt : IF LEFTBRACKET expression RIGHTBRACKET statement {$$ = newStmtNode(SelectK);
$$->nodeChild[0] = $3; $$->nodeChild[1] = $5;
$$->lineno = yylineno;$$->local_size = $5->local_size;}
| IF LEFTBRACKET expression RIGHTBRACKET statement ELSE statement {$$ = newStmtNode(SelectK); $$->nodeChild[0] = $3;
$$->nodeChild[1] = $5; $$->nodeChild[2] = $7;$$->lineno = yylineno;
$$->local_size = $5->local_size + $7->local_size;}
;
iteration_stmt : WHILE LEFTBRACKET expression RIGHTBRACKET statement {$$ = newStmtNode(IteraK); $$->nodeChild[0] = $3;
$$->nodeChild[1] = $5;$$->lineno = yylineno;
$$->local_size = $5->local_size;}
;
return_stmt : RETURN SEMICOLON {$$ = newStmtNode(ReturnK);$$->lineno = yylineno;}
| RETURN expression SEMICOLON {$$ = newStmtNode(ReturnK); $$->nodeChild[0] = $2;$$->lineno = yylineno;}
;
expression : var ASSIGNMENT expression {$$=newExpNode(AssignK); $$->nodeChild[0] = $1; $$->nodeChild[1] = $3;$$->lineno = yylineno;}
| simple_expression {$$ = $1;$$->lineno = yylineno;}
;
var : ID {$$ = newExpNode(IdK); $$->name = $1;$$->lineno = yylineno;}
| ID LEFTSQUAREBRACKET expression RIGHTSQUAREBRACKET {$$ = newStmtNode(ArrayK); $$->name=$1;$$->nodeChild[0] = $3;$$->lineno = yylineno;$$->isArray = 1;}
;
simple_expression : additive_expression LESSEQUAL additive_expression {$$ = newExpNode(OpK); $$->type=8;$$->nodeChild[0] = $1; $$->nodeChild[1] = $3; $$->op = $2;$$->lineno = yylineno;}
| additive_expression LESS additive_expression {$$ = newExpNode(OpK); $$->type=6;$$->nodeChild[0]= $1; $$->nodeChild[1] = $3; $$->op = $2;$$->lineno = yylineno;}
| additive_expression GREATER additive_expression {$$ = newExpNode(OpK); $$->type=9;$$->nodeChild[0]= $1; $$->nodeChild[1] = $3; $$->op = $2;$$->lineno = yylineno;}
| additive_expression GREATEREQUAL additive_expression {$$ = newExpNode(OpK); $$->type=10;$$->nodeChild[0]= $1; $$->nodeChild[1] = $3; $$->op = $2;$$->lineno = yylineno;}
| additive_expression EQUAL additive_expression {$$ = newExpNode(OpK); $$->type=7;$$->nodeChild[0]= $1; $$->nodeChild[1] = $3; $$->op = $2;$$->lineno = yylineno;}
| additive_expression UNEQUAL additive_expression {$$ = newExpNode(OpK); $$->type=11;$$->nodeChild[0]= $1; $$->nodeChild[1] = $3; $$->op = $2;$$->lineno = yylineno;}
| additive_expression {$$ = $1;$$->lineno = yylineno;}
;
additive_expression : additive_expression PLUS term { $$ = newExpNode(OpK); $$->op = $2; $$->type=2;$$->nodeChild[0] = $1; $$->nodeChild[1] = $3;$$->lineno = yylineno;}
| additive_expression MINUS term { $$ = newExpNode(OpK); $$->op = $2; $$->type=3;$$->nodeChild[0]= $1; $$->nodeChild[1] = $3;$$->lineno = yylineno;}
| term { $$ = $1;$$->lineno = yylineno;}
;
term : term MULTI factor {$$ = newExpNode(OpK); $$->op = $2; $$->type=4;$$->nodeChild[0] = $1; $$->nodeChild[1] = $3;$$->lineno = yylineno;}
| term DIVIDE factor {$$ = newExpNode(OpK); $$->op = $2; $$->type=5;$$->nodeChild[0] = $1; $$->nodeChild[1] = $3;$$->lineno = yylineno;}
| factor {$$ = $1;$$->lineno = yylineno;}
;
factor : LEFTBRACKET expression RIGHTBRACKET {$$ = $2;$$->lineno = yylineno;}
| var {$$ = $1;$$->lineno = yylineno;}
| call {$$ = $1;$$->lineno = yylineno;}
| NUM {$$ = newExpNode(ConstK); $$->val = $1;$$->lineno = yylineno;}
;
call : ID LEFTBRACKET args RIGHTBRACKET {$$ = newStmtNode(CallK); $$->nodeChild[0] = $3; $$->name = $1;$$->lineno = yylineno;}
| ID LEFTBRACKET RIGHTBRACKET {$$ = newStmtNode(CallK); $$->name = $1;$$->lineno = yylineno;}
;
args : args COMMA expression {addNode($1, $3); $$ = $1;$$->lineno = yylineno; $$->param_size += 1;}
| expression {$$ = newStmtNode(ArgsK); addNode($$, $1);$$->lineno = yylineno; $$->param_size += 1;}
;
%%
/**
* @description: 处理解析错误并打印到文件
* @param {void}
* @return: void
* @author: David.Huangjunlang
*/
void yyerror(const char *s){
fprintf(result ,"error: %s\n in line : %d\n unexpected token: %s\n", s, yylineno, yytext);
yywrap();
}