-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstatement.cpp
347 lines (333 loc) · 7.3 KB
/
statement.cpp
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
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
/*
所有语句的语法分析程序
<语句>::=<赋值语句>|<条件语句>|<当循环语句>|<过程调用语句>|<复合语句>|
<读语句>|<写语句>|<for循环语句>|<空>
*/
#include "global.h"
#include "support.h"
#include "statement.h"
#include "express.h"
extern int symbol;
extern int lex();
//语句
AST_node statement(AST_node parent)
{
AST_node t = makeNode(STATEMENT, parent);
if (symbol == IDENT)
{
//赋值语句或者过程调用语句
//<赋值语句>::=<标识符>:=<表达式>|<函数标识符>:=<表达式>|<标识符>'['<表达式>']':=<表达式>
//<过程调用语句>::=<标识符>[<实在参数表>]
match(IDENT,t);
if (symbol == BECOMES || symbol == LBRACKET)
{
//赋值语句
stat_assign(t);
}
else if (symbol == LPARENT || symbol == SEMICOLON
|| symbol == END //过程调用语句在end前,可以没有分号
)
{
//过程调用语句
stat_procedure(t);
}
else
{
error("Unknown Statement!");
recovery(2, SEMICOLON, END);
}
}
else if (symbol == IF)
{
//条件语句
//<条件语句>::=if<条件>then<语句>|if<条件>then<语句>else<语句>
stat_if(t);
}
else if (symbol == DO)
{
//当循环语句
//<当循环语句>::=do<语句>while<条件>
stat_do(t);
}
else if (symbol == FOR)
{
//for循环语句
//<for循环语句>::=for<标识符>:=<表达式>(downto|to)<表达式>do<语句>//步长为1
stat_for(t);
}
else if (symbol == BEGIN)
{
//复合语句
//<复合语句>::=begin<语句>{;<语句>}end
stat_list(t);
}
else if (symbol == READ)
{
//读语句
//<读语句>::=read'('<标识符>{,<标识符>}')'
stat_read(t);
}
else if (symbol == WRITE)
{
//写语句
//<写语句>::=write'('<字符串>,<表达式>')'|write'('<字符串>')'|write'('<表达式>')'
stat_write(t);
}
else
{
//空语句
t->ast_type = EMPTY;
printf("----------------Empty Statement--------------\n");
}
return 0;
}
//复合语句
//<复合语句>::=begin<语句>{;<语句>}end
AST_node stat_list(AST_node t)
{
printf("----------------Statement List--------------\n");
t->ast_type = STATS;
match(BEGIN,t);
statement(t);
while (match(SEMICOLON,t))
{
statement(t);
}
if (!match(END,t))
{
error("Missing Semicolon or \"end\"");
}
printf("----------------End of Statement List--------------\n");
return t;
}
//赋值语句
//<赋值语句>::=<标识符>:=<表达式>|<函数标识符>:=<表达式>|<标识符>'['<表达式>']':=<表达式>
AST_node stat_assign(AST_node t)
{
//由于区别赋值语句与过程调用语句,所以IDENT已经被匹配
printf("---------------------Assignment--------------\n");
t->ast_type = ASSIGNSTAT;
if (match(LBRACKET, t))
{
express(t);
if (!match(RBRACKET,t))
{
error("Missing right bracket");
recovery(1, BECOMES);
}
}
match(BECOMES,t);
express(t);
printf("----------------------End of Assignment---------\n");
return t;
}
//过程调用语句
//<过程调用语句>::=<标识符>[<实在参数表>]
AST_node stat_procedure(AST_node t)
{
printf("-------------------Procedure Call-----------\n");
t->ast_type = CALL;
if (symbol == LPARENT)
{
//参数表
arg_list(t);
}
printf("----------------End of Procedure Call---------\n");
return t;
}
//实在参数表
//<实在参数表>::='('<实在参数>{,<实在参数>}')'
AST_node arg_list(AST_node parent)
{
AST_node t = makeNode(ARGLIST, parent);
match(LPARENT,t);
express(t);
while (match(COMMA,t))
{
//实在参数
//<实在参数>::=<表达式>
express(t);
}
if (!match(RPARENT,t))
{
error("Missing Right Parent");
recovery(3, RPARENT, SEMICOLON, END);
}
return t;
}
//for语句
//<for循环语句>::=for<标识符>:=<表达式>(downto|to)<表达式>do<语句>
AST_node stat_for(AST_node t)
{
printf("----------------For Loop--------------\n");
t->ast_type = FORSTAT;
match(FOR,t);
if (!match(IDENT,t))
{
error("Missing identifier for \"for-statement\"");
recovery(1, BECOMES);
}
if (!match(BECOMES,t))
{
error("Missing assign symbol");
recovery(5, PLUS, MINUS, IDENT, LPARENT, NUM);
}
express(t);
if (!match(DOWNTO,t))
{
if (!match(TO,t))
{
error("Missing \"downto\" or \"to\"");
recovery(5, IDENT, MINUS, PLUS, NUM, LPARENT);
}
}
express(t);
if (!match(DO,t))
{
error("Missing do clause");
//因为可能是空语句,所以不需要错误恢复
//recovery(IDENT, IF, FOR, BEGIN, READ, WRITE);
}
AST_node stat = makeNode(STATS, t);
statement(stat);
printf("----------------End of For Loop--------------\n");
return t;
}
//当循环语句
//<当循环语句>::=do<语句>while<条件>
AST_node stat_do(AST_node t)
{
printf("----------------Do While Loop--------------\n");
t->ast_type = DOSTAT;
match(DO,t);
AST_node stat = makeNode(STATS, t);
statement(stat);
if (!match(WHILE,t))
{
error("Missing while clause");
//错误恢复:跳至条件的first集
recovery(5, PLUS, MINUS, IDENT, NUM, LPARENT);
}
condition(t);
printf("----------------End of Do While Loop--------------\n");
return t;
}
//条件语句
//<条件语句>::=if<条件>then<语句>|if<条件>then<语句>else<语句>
AST_node stat_if(AST_node t)
{
printf("----------------If Statement--------------\n");
t->ast_type = IFSTAT;
match(IF,t);
condition(t);
if (!match(THEN,t))
{
error("Missing \"then\" clause");
recovery(8, IDENT, IF, DO, BEGIN, READ, WRITE, FOR, SEMICOLON, ELSE);
}
statement(t);
if (match(ELSE,t))
{
//有else分支
statement(t);
}
printf("----------------End of If--------------\n");
return t;
}
//条件
//<条件>::=<表达式><关系运算符><表达式>
AST_node condition(AST_node parent)
{
AST_node t = makeNode(CONDITION, parent);
express(t);
if (match(LEQ, t))
{
}
else if (match(LESS, t))
{
}
else if (match(EQL, t))
{
}
else if (match(GEQ, t))
{
}
else if (match(GREATER, t))
{
}
else if (match(NEQ, t))
{
}
else
{
error("Missing Relation Operator");
//错误恢复:跳至<表达式>的first集
recovery(5, PLUS, MINUS, IDENT, NUM, LPARENT);
}
express(t);
return t;
}
//写语句
//<写语句>::=write'('<字符串>,<表达式>')'|write'('<字符串>')'|write'('<表达式>')'
AST_node stat_write(AST_node t)
{
printf("----------------Write Statement--------------\n");
t->ast_type = WRITESTAT;
match(WRITE,t);
if (!match(LPARENT,t))
{
error("Missing left parenthesis");
recovery(6, STRING, MINUS, PLUS, IDENT, LPARENT, NUM);
}
if (match(STRING,t))
{
if (match(COMMA,t))
{
express(t);
}
}
else
{
express(t);
}
if (!match(RPARENT,t))
{
error("Missing right parenthesis");
recovery(9, SEMICOLON, END, IDENT, IF, DO, BEGIN, READ, WRITE, FOR);
}
printf("----------------End of Write--------------\n");
return t;
}
//读语句
//<读语句>::=read'('<标识符>{,<标识符>}')'
AST_node stat_read(AST_node t)
{
printf("----------------Read Statement--------------\n");
t->ast_type = READSTAT;
match(READ,t);
if (!match(LPARENT,t))
{
error("Missing left parenthesis");
recovery(1, IDENT);
}
if (!match(IDENT,t))
{
error("Wrong args");
recovery(10, COMMA, RPARENT, IDENT, IF, DO, BEGIN, READ, WRITE, FOR, END);
}
while (match(COMMA,t))
{
if (!match(IDENT,t))
{
error("Wrong args");
recovery(2, COMMA, RPARENT);
}
}
if (!match(RPARENT,t))
{
error("Missing right parenthesis");
recovery(2, END, SEMICOLON);
}
printf("----------------End of Read--------------\n");
return t;
}