1
//-----------------------------parser.h---------------------------------
2
#ifndef PARSER_H
3
#define PARSER_H
4
5
#include "scanner.h"
6
7
typedef double (*FuncPtr)(double);
8
struct ExprNode // 语法树节点类型
9
{
10
enum Token_Type OpCode;
11
union
12
{
13
struct
14
{
15
ExprNode *Left, *Right;
16
} CaseOperator;
17
struct
18
{
19
ExprNode *Child;
20
FuncPtr MathFuncPtr;
21
} CaseFunc;
22
double CaseConst;
23
double *CaseParmPtr;
24
} Content;
25
};
26
27
extern void Parser(char *SrcFilePtr); // 语法分析器对外的接口
28
29
#endif
//-----------------------------parser.h---------------------------------2
#ifndef PARSER_H3
#define PARSER_H4

5
#include "scanner.h"6

7
typedef double (*FuncPtr)(double);8
struct ExprNode // 语法树节点类型9
{10
enum Token_Type OpCode;11
union12
{13
struct 14
{ 15
ExprNode *Left, *Right; 16
} CaseOperator;17
struct 18
{ 19
ExprNode *Child; 20
FuncPtr MathFuncPtr; 21
} CaseFunc;22
double CaseConst;23
double *CaseParmPtr;24
} Content;25
};26

27
extern void Parser(char *SrcFilePtr); // 语法分析器对外的接口28

29
#endif 1
//-------------------------parser.cpp-----------------------------
2
3
#include "parser.h"
4
5
#define PARSER_DEBUG
6
7
#ifndef PARSER_DEBUG
8
#include "semantic.h"
9
#endif
10
11
#ifdef PARSER_DEBUG
12
#define enter(x) printf("enter in "); printf(x); printf("\n")
13
#else
14
#define enter(x)
15
#endif
16
17
#ifdef PARSER_DEBUG
18
#define back(x) printf("exit from "); printf(x); printf("\n")
19
#else
20
#define back(x)
21
#endif
22
23
#ifdef PARSER_DERBUG
24
#define call_match(x) printf("match token "); printf(x); printf("\n")
25
#else
26
#define call_match(x)
27
#endif
28
29
#ifdef PARSER_DEBUG
30
#define Tree_trace(x) PrintSyntaxTree(x, 1);
31
#else
32
#define Tree_trace
33
#endif
34
35
#ifdef PARSER_DEBUG
36
double Parameter = 0; //参数T的存储空间
37
#else
38
double Parameter = 0, //参数存储空间
39
Origin_x = 0, Origin_y = 0, //横纵坐标平移距离
40
Scale_x = 1,Scale_y = 1, //横纵比例因子
41
Rot_angle = 0; //旋转角度
42
#endif
43
44
static Token token; //记号
45
46
47
// ------------辅助函数声明
48
static void FetchToken();
49
static void MatchToken(enum Token_Type AToken);
50
static void SyntaxError(int case_of);
51
static void ErrMsg(unsigned LineNo, char *descrip, char *string);
52
static void PrintSyntaxTree(struct ExprNode *root, int indent);
53
54
// ------------非终结符的递归子程序声明
55
static void Program();
56
static void Statement();
57
static void OriginStatement();
58
static void RotStatement();
59
static void ScaleStatement();
60
static void ForStatement();
61
static struct ExprNode *Expression();
62
static struct ExprNode *Term();
63
static struct ExprNode *Factor();
64
static struct ExprNode *Component();
65
static struct ExprNode *Atom();
66
67
// -------------外部接口与语法树构造函数声明
68
extern void Parser(char *SrcFilePtr);
69
static struct ExprNode *MakeExprNode(enum Token_Type opcode,
);
70
71
// -------------通过词法分析器接口GetToken获取一个记号
72
static void FetchToken()
73
{
74
token = GetToken();
75
if(token.type == ERRTOKEN) SyntaxError(1);
76
}
77
78
// -------------匹配记号
79
static void MatchToken(enum Token_Type The_Token)
80
{
81
if(token.type != The_Token) SyntaxError(2);
82
FetchToken();
83
}
84
85
// -------------语法错误处理
86
static void SyntaxError(int case_of)
87
{
88
switch(case_of)
89
{
90
case 1: ErrMsg(LineNo, "错误记号", token.lexeme);
91
break;
92
case 2: ErrMsg(LineNo, "不是预期记号", token.lexeme);
93
break;
94
}
95
}
96
97
// -------------打印错误信息
98
void ErrMsg(unsigned int LineNo, char *descrip, char *string)
99
{
100
#ifdef PARSER_DEBUG
101
printf("Line No %5d:%s %s !\n", LineNo, descrip, string);
102
#else
103
char msg[256];
104
memset(msg, 0, 256);
105
sprintf("Line No %5d:%s %s !\n", LineNo, descrip, string);
106
#endif
107
108
#ifdef _VC_COMPILER
109
MessageBox(NULL,msg"error!",MB_OK);
110
#endif
111
112
#ifdef _BC_COMPILER
113
printf("%s\n",msg);
114
#endif
115
116
CloseScanner();
117
exit(1);
118
}
119
120
// -------------先序遍历并打印表达式的语法树
121
void PrintSyntaxTree(struct ExprNode *root, int indent)
122
{
123
int temp;
124
for(temp = 1; temp <= indent; ++temp) printf("\t"); // 缩进
125
switch(root->OpCode)
126
{
127
case PLUS : printf("%s\n", "+");break;
128
case MINUS : printf("%s\n", "-");break;
129
case MUL : printf("%s\n", "*");break;
130
case DIV : printf("%s\n", "/");break;
131
case POWER : printf("%s\n", "**");break;
132
case FUNC : printf("%x\n", root->Content.CaseFunc.MathFuncPtr);break;
133
case CONST_ID : printf("%f\n", root->Content.CaseConst);break;
134
case T: printf("%s\n", "T");break;
135
default: printf("Error Tree Node!\n");exit(0);
136
}
137
if(root->OpCode == CONST_ID || root->OpCode == T) //叶子节点返回
138
return;
139
if(root->OpCode == FUNC) //递归打印一个孩子的节点
140
PrintSyntaxTree(root->Content.CaseFunc.Child, indent+1);
141
else //递归打印两个孩子的节点
142
{
143
PrintSyntaxTree(root->Content.CaseOperator.Left, indent+1);
144
PrintSyntaxTree(root->Content.CaseOperator.Right, indent+1);
145
}
146
}
147
148
// -------------绘图语言解释器入口(与主程序的外部接口)
149
void Parser(char *SrcFilePtr)
150
{
151
enter("Parser");
152
if(!InitScanner(SrcFilePtr)) //初始化词法分析器
153
{
154
printf("Open Source File Error!\n");
155
return;
156
}
157
FetchToken(); //获取第一个记号
158
Program(); //递归下降分析
159
CloseScanner(); //关闭词法分析器
160
back("Parser");
161
return;
162
}
163
164
// -------------Program的递归子程序
165
static void Program()
166
{
167
enter("Program");
168
while(token.type != NONTOKEN)
169
{
170
Statement();
171
MatchToken(SEMICO);
172
}
173
back("Program");
174
}
175
176
// --------------Statement的递归子程序
177
static void Statement()
178
{
179
enter("Statement");
180
switch(token.type)
181
{
182
case ORIGIN : OriginStatement(); break;
183
case SCALE : ScaleStatement(); break;
184
case ROT : RotStatement(); break;
185
case FOR : ForStatement(); break;
186
default : SyntaxError(2); break;
187
}
188
back("Statement");
189
}
190
191
// -------------OriginStatement的递归子程序
192
static void OriginStatement(void)
193
{
194
struct ExprNode *tmp;
195
196
enter("OriginStatement");
197
MatchToken(ORIGIN);
198
MatchToken(IS);
199
MatchToken(L_BRACKET);
200
tmp = Expression();
201
202
#ifndef PARSER_DEBUG
203
Origin_x = GetExprValue(tmp); // 获取横坐标的平移距离
204
DelExprTree(tmp);
205
#endif
206
207
MatchToken(COMMA);
208
tmp = Expression();
209
210
#ifndef PARSER_DEBUG
211
Origin_y = GetExprValue(tmp); // 获取纵坐标的平移距离
212
DelExprTree(tmp);
213
#endif
214
215
MatchToken(R_BRACKET);
216
back("OriginStatement");
217
}
218
219
// -------------ScaleStatement的递归子程序
220
static void ScaleStatement(void)
221
{
222
struct ExprNode *tmp;
223
224
enter("ScaleStatement");
225
MatchToken(SCALE);
226
MatchToken(IS);
227
MatchToken(L_BRACKET);
228
tmp = Expression();
229
230
#ifndef PARSER_DEBUG
231
Scale_x = GetExprValue(tmp); //获取横坐标的比例因子
232
DelExprTree(tmp);
233
#endif
234
235
MatchToken(COMMA);
236
tmp = Expression();
237
238
#ifndef PARSER_DEBUG
239
Scale_y = GetExprValue(tmp); //获取纵坐标的比例因子
240
DelExprTree(tmp);
241
#endif
242
243
MatchToken(R_BRACKET);
244
back("ScaleStatement");
245
}
246
247
// -------------RotStatement的递归子程序
248
static void RotStatement(void)
249
{
250
struct ExprNode *tmp;
251
252
enter("RotStatement");
253
MatchToken(ROT);
254
MatchToken(IS);
255
tmp = Expression();
256
257
#ifndef PARSER_DEBUG
258
Rot_angle = GetExprValue(tmp); //获取旋转角度
259
DelExprTree(tmp);
260
#endif
261
262
back("RotStatement");
263
}
264
265
// -------------ForStatement的递归子程序
266
static void ForStatement(void)
267
{
268
269
#ifndef PARSER_DEBUG
270
double Start, End, Step; //绘图起点, 终点, 步长
271
#endif
272
273
struct ExprNode *start_ptr, *end_ptr, *step_ptr, *x_ptr, *y_ptr;
274
//各表达式语法树根节点指针
275
276
enter("ForStatement");
277
278
MatchToken(FOR); call_match("FOR");
279
MatchToken(T); call_match("T");
280
MatchToken(FROM); call_match("FROM");
281
282
start_ptr = Expression(); //构造参数起点表达式语法树
283
284
#ifndef PARSER_DEBUG
285
Start = GetExprValue(start_ptr); //计算参数起点表达式的值
286
DelExprTree(start_ptr); //释放参数起点语法树所占空间
287
#endif
288
289
MatchToken(TO); call_match("TO");
290
end_ptr = Expression(); //构造参数终点表达式语法树
291
292
#ifndef PARSER_DEBUG
293
End = GetExprValue(end_ptr); //计算参数终点表达式
294
DelExprTree(end_ptr); //释放参数终点语法树所占空间
295
#endif
296
297
MatchToken(STEP); call_match("STEP");
298
step_ptr = Expression(); //构造参数步长表达式语法树
299
300
#ifndef PARSER_DEBUG
301
Step = GetExprValue(step_ptr); //计算参数步长表达式值
302
DelExprTree(step_ptr); //释放参数步长语法树所占空间
303
#endif
304
305
MatchToken(DRAW); call_match("DRAW");
306
MatchToken(L_BRACKET); call_match("(");
307
x_ptr = Expression(); //构造横坐标表达式语法树
308
MatchToken(COMMA); call_match(",");
309
y_ptr = Expression(); //构造纵坐标表达式语法树
310
MatchToken(R_BRACKET); call_match(")");
311
312
#ifndef PARSER_DEBUG
313
DrawLoop(Start, End, Step, x_ptr, y_ptr); //绘制图形
314
DelExprTree(x_ptr); //释放横坐标语法树所占空间
315
DelExprTree(y_ptr); //释放纵坐标语法树所占空间
316
#endif
317
318
back("ForStatement");
319
}
320
321
// -------------Expression的递归子程序
322
static struct ExprNode * Expression()
323
{
324
struct ExprNode *left, *right; //左右子树节点的指针
325
Token_Type token_tmp; //当前记号
326
327
enter("Expression");
328
left = Term(); //分析左操作数且得到其语法树
329
while(token.type == PLUS || token.type == MINUS)
330
{
331
token_tmp = token.type;
332
MatchToken(token_tmp);
333
right = Term(); //分析右操作数且得到其语法树
334
left = MakeExprNode(token_tmp, left, right);
335
//构造运算的语法树, 结果为左子树
336
}
337
Tree_trace(left); //打印表达式的语法树
338
back("Expression");
339
return left; //返回最终表达式的语法树
340
}
341
342
// -------------Term的递归子程序
343
static struct ExprNode *Term()
344
{
345
struct ExprNode *left, *right;
346
Token_Type token_tmp;
347
348
left = Factor();
349
while(token.type == MUL || token.type == DIV)
350
{
351
token_tmp = token.type;
352
MatchToken(token_tmp);
353
right = Factor();
354
left = MakeExprNode(token_tmp, left, right);
355
}
356
return left;
357
}
358
359
// -------------Factor的递归子程序
360
static struct ExprNode * Factor()
361
{
362
struct ExprNode *left, *right;
363
364
if(token.type == PLUS) //匹配一元加运算
365
{
366
MatchToken(PLUS);
367
right = Factor(); //表达式退化为仅有右操作数的表达式
368
}
369
else if(token.type == MINUS) //匹配一元减运算
370
{
371
MatchToken(MINUS); //表达式转化为二元减运算的表达式
372
right = Factor();
373
left = new ExprNode;
374
left->OpCode = CONST_ID;
375
left->Content.CaseConst = 0.0;
376
right = MakeExprNode(MINUS, left, right);
377
}
378
else right = Component(); //匹配非终结符Component
379
380
return right;
381
}
382
383
// -------------Comoenent的递归子程序
384
static struct ExprNode *Component()
385
{
386
struct ExprNode *left, *right;
387
388
left = Atom();
389
if(token.type == POWER)
390
{
391
MatchToken(POWER);
392
right = Component(); //递归调用Component以实现POWER的右集合
393
left = MakeExprNode(POWER, left, right);
394
}
395
return left;
396
}
397
398
// -------------Atom的递归子程序
399
static struct ExprNode *Atom()
400
{
401
struct Token t = token;
402
struct ExprNode *address, *tmp;
403
404
switch(token.type)
405
{
406
case CONST_ID :
407
MatchToken(CONST_ID);
408
address = MakeExprNode(CONST_ID, t.value);
409
break;
410
case T :
411
MatchToken(T);
412
address = MakeExprNode(T);
413
break;
414
case FUNC :
415
MatchToken(FUNC);
416
MatchToken(L_BRACKET);
417
tmp = Expression();
418
address = MakeExprNode(FUNC, t.FuncPtr, tmp);
419
MatchToken(R_BRACKET);
420
break;
421
case L_BRACKET :
422
MatchToken(L_BRACKET);
423
address = Expression();
424
MatchToken(R_BRACKET);
425
break;
426
default :
427
SyntaxError(2);
428
}
429
return address;
430
}
431
432
433
// -------------生成语法树的一个结点
434
static struct ExprNode *MakeExprNode(enum Token_Type opcode,
)
435
{
436
struct ExprNode *ExprPtr = new (struct ExprNode);
437
ExprPtr->OpCode = opcode; //接收记号的种类
438
va_list ArgPtr;
439
va_start(ArgPtr, opcode);
440
switch(opcode) //根据记号的类别构造不同的节点
441
{
442
case CONST_ID : //常数节点
443
ExprPtr->Content.CaseConst = (double)va_arg(ArgPtr, double);
444
break;
445
case T : //参数节点
446
ExprPtr->Content.CaseParmPtr = &Parameter;
447
break;
448
case FUNC : //函数调用节点
449
ExprPtr->Content.CaseFunc.MathFuncPtr = (FuncPtr)va_arg(ArgPtr, FuncPtr);
450
ExprPtr->Content.CaseFunc.Child = (struct ExprNode *)va_arg(ArgPtr, struct ExprNode *);
451
break;
452
default :
453
ExprPtr->Content.CaseOperator.Left = (struct ExprNode *)va_arg(ArgPtr, struct ExprNode *);
454
ExprPtr->Content.CaseOperator.Right = (struct ExprNode *)va_arg(ArgPtr, struct ExprNode *);
455
break;
456
}
457
va_end(ArgPtr);
458
459
return ExprPtr;
460
}
//-------------------------parser.cpp-----------------------------2

3
#include "parser.h"4

5
#define PARSER_DEBUG6

7
#ifndef PARSER_DEBUG8
#include "semantic.h"9
#endif10

11
#ifdef PARSER_DEBUG12
#define enter(x) printf("enter in "); printf(x); printf("\n")13
#else14
#define enter(x)15
#endif16

17
#ifdef PARSER_DEBUG18
#define back(x) printf("exit from "); printf(x); printf("\n")19
#else20
#define back(x)21
#endif22

23
#ifdef PARSER_DERBUG24
#define call_match(x) printf("match token "); printf(x); printf("\n")25
#else26
#define call_match(x)27
#endif28

29
#ifdef PARSER_DEBUG30
#define Tree_trace(x) PrintSyntaxTree(x, 1);31
#else32
#define Tree_trace33
#endif34

35
#ifdef PARSER_DEBUG36
double Parameter = 0; //参数T的存储空间37
#else38
double Parameter = 0, //参数存储空间39
Origin_x = 0, Origin_y = 0, //横纵坐标平移距离40
Scale_x = 1,Scale_y = 1, //横纵比例因子41
Rot_angle = 0; //旋转角度42
#endif43

44
static Token token; //记号45

46

47
// ------------辅助函数声明48
static void FetchToken();49
static void MatchToken(enum Token_Type AToken);50
static void SyntaxError(int case_of);51
static void ErrMsg(unsigned LineNo, char *descrip, char *string);52
static void PrintSyntaxTree(struct ExprNode *root, int indent);53

54
// ------------非终结符的递归子程序声明55
static void Program();56
static void Statement();57
static void OriginStatement();58
static void RotStatement();59
static void ScaleStatement();60
static void ForStatement();61
static struct ExprNode *Expression();62
static struct ExprNode *Term();63
static struct ExprNode *Factor();64
static struct ExprNode *Component();65
static struct ExprNode *Atom();66

67
// -------------外部接口与语法树构造函数声明68
extern void Parser(char *SrcFilePtr);69
static struct ExprNode *MakeExprNode(enum Token_Type opcode,
);70

71
// -------------通过词法分析器接口GetToken获取一个记号72
static void FetchToken()73
{74
token = GetToken();75
if(token.type == ERRTOKEN) SyntaxError(1);76
}77

78
// -------------匹配记号79
static void MatchToken(enum Token_Type The_Token)80
{81
if(token.type != The_Token) SyntaxError(2);82
FetchToken();83
}84

85
// -------------语法错误处理86
static void SyntaxError(int case_of)87
{88
switch(case_of)89
{90
case 1: ErrMsg(LineNo, "错误记号", token.lexeme);91
break;92
case 2: ErrMsg(LineNo, "不是预期记号", token.lexeme);93
break;94
}95
}96

97
// -------------打印错误信息98
void ErrMsg(unsigned int LineNo, char *descrip, char *string)99
{100
#ifdef PARSER_DEBUG101
printf("Line No %5d:%s %s !\n", LineNo, descrip, string);102
#else103
char msg[256];104
memset(msg, 0, 256);105
sprintf("Line No %5d:%s %s !\n", LineNo, descrip, string);106
#endif107

108
#ifdef _VC_COMPILER109
MessageBox(NULL,msg"error!",MB_OK);110
#endif111

112
#ifdef _BC_COMPILER113
printf("%s\n",msg);114
#endif115

116
CloseScanner();117
exit(1);118
}119

120
// -------------先序遍历并打印表达式的语法树121
void PrintSyntaxTree(struct ExprNode *root, int indent)122
{123
int temp;124
for(temp = 1; temp <= indent; ++temp) printf("\t"); // 缩进125
switch(root->OpCode)126
{127
case PLUS : printf("%s\n", "+");break;128
case MINUS : printf("%s\n", "-");break;129
case MUL : printf("%s\n", "*");break;130
case DIV : printf("%s\n", "/");break;131
case POWER : printf("%s\n", "**");break;132
case FUNC : printf("%x\n", root->Content.CaseFunc.MathFuncPtr);break;133
case CONST_ID : printf("%f\n", root->Content.CaseConst);break;134
case T: printf("%s\n", "T");break;135
default: printf("Error Tree Node!\n");exit(0);136
}137
if(root->OpCode == CONST_ID || root->OpCode == T) //叶子节点返回138
return;139
if(root->OpCode == FUNC) //递归打印一个孩子的节点140
PrintSyntaxTree(root->Content.CaseFunc.Child, indent+1);141
else //递归打印两个孩子的节点142
{143
PrintSyntaxTree(root->Content.CaseOperator.Left, indent+1);144
PrintSyntaxTree(root->Content.CaseOperator.Right, indent+1);145
}146
}147

148
// -------------绘图语言解释器入口(与主程序的外部接口)149
void Parser(char *SrcFilePtr)150
{151
enter("Parser");152
if(!InitScanner(SrcFilePtr)) //初始化词法分析器153
{154
printf("Open Source File Error!\n"); 155
return;156
}157
FetchToken(); //获取第一个记号158
Program(); //递归下降分析159
CloseScanner(); //关闭词法分析器160
back("Parser");161
return;162
}163

164
// -------------Program的递归子程序165
static void Program()166
{167
enter("Program");168
while(token.type != NONTOKEN)169
{170
Statement();171
MatchToken(SEMICO);172
}173
back("Program");174
}175

176
// --------------Statement的递归子程序177
static void Statement()178
{179
enter("Statement");180
switch(token.type)181
{182
case ORIGIN : OriginStatement(); break;183
case SCALE : ScaleStatement(); break;184
case ROT : RotStatement(); break;185
case FOR : ForStatement(); break;186
default : SyntaxError(2); break;187
}188
back("Statement");189
}190

191
// -------------OriginStatement的递归子程序192
static void OriginStatement(void)193
{194
struct ExprNode *tmp;195

196
enter("OriginStatement");197
MatchToken(ORIGIN);198
MatchToken(IS);199
MatchToken(L_BRACKET);200
tmp = Expression();201

202
#ifndef PARSER_DEBUG203
Origin_x = GetExprValue(tmp); // 获取横坐标的平移距离204
DelExprTree(tmp);205
#endif206

207
MatchToken(COMMA);208
tmp = Expression();209

210
#ifndef PARSER_DEBUG211
Origin_y = GetExprValue(tmp); // 获取纵坐标的平移距离212
DelExprTree(tmp);213
#endif214

215
MatchToken(R_BRACKET);216
back("OriginStatement");217
}218

219
// -------------ScaleStatement的递归子程序220
static void ScaleStatement(void)221
{222
struct ExprNode *tmp;223

224
enter("ScaleStatement");225
MatchToken(SCALE);226
MatchToken(IS);227
MatchToken(L_BRACKET);228
tmp = Expression();229

230
#ifndef PARSER_DEBUG231
Scale_x = GetExprValue(tmp); //获取横坐标的比例因子232
DelExprTree(tmp);233
#endif234

235
MatchToken(COMMA);236
tmp = Expression();237

238
#ifndef PARSER_DEBUG239
Scale_y = GetExprValue(tmp); //获取纵坐标的比例因子240
DelExprTree(tmp);241
#endif242

243
MatchToken(R_BRACKET);244
back("ScaleStatement");245
}246

247
// -------------RotStatement的递归子程序248
static void RotStatement(void)249
{250
struct ExprNode *tmp;251

252
enter("RotStatement");253
MatchToken(ROT);254
MatchToken(IS);255
tmp = Expression();256

257
#ifndef PARSER_DEBUG258
Rot_angle = GetExprValue(tmp); //获取旋转角度259
DelExprTree(tmp);260
#endif261

262
back("RotStatement");263
}264

265
// -------------ForStatement的递归子程序266
static void ForStatement(void)267
{268

269
#ifndef PARSER_DEBUG270
double Start, End, Step; //绘图起点, 终点, 步长271
#endif272

273
struct ExprNode *start_ptr, *end_ptr, *step_ptr, *x_ptr, *y_ptr; 274
//各表达式语法树根节点指针275

276
enter("ForStatement");277

278
MatchToken(FOR); call_match("FOR");279
MatchToken(T); call_match("T");280
MatchToken(FROM); call_match("FROM");281

282
start_ptr = Expression(); //构造参数起点表达式语法树283

284
#ifndef PARSER_DEBUG285
Start = GetExprValue(start_ptr); //计算参数起点表达式的值286
DelExprTree(start_ptr); //释放参数起点语法树所占空间287
#endif288

289
MatchToken(TO); call_match("TO");290
end_ptr = Expression(); //构造参数终点表达式语法树291

292
#ifndef PARSER_DEBUG293
End = GetExprValue(end_ptr); //计算参数终点表达式294
DelExprTree(end_ptr); //释放参数终点语法树所占空间295
#endif296

297
MatchToken(STEP); call_match("STEP");298
step_ptr = Expression(); //构造参数步长表达式语法树299

300
#ifndef PARSER_DEBUG301
Step = GetExprValue(step_ptr); //计算参数步长表达式值302
DelExprTree(step_ptr); //释放参数步长语法树所占空间303
#endif304

305
MatchToken(DRAW); call_match("DRAW");306
MatchToken(L_BRACKET); call_match("(");307
x_ptr = Expression(); //构造横坐标表达式语法树308
MatchToken(COMMA); call_match(",");309
y_ptr = Expression(); //构造纵坐标表达式语法树310
MatchToken(R_BRACKET); call_match(")");311

312
#ifndef PARSER_DEBUG313
DrawLoop(Start, End, Step, x_ptr, y_ptr); //绘制图形314
DelExprTree(x_ptr); //释放横坐标语法树所占空间315
DelExprTree(y_ptr); //释放纵坐标语法树所占空间316
#endif317

318
back("ForStatement");319
}320

321
// -------------Expression的递归子程序322
static struct ExprNode * Expression()323
{324
struct ExprNode *left, *right; //左右子树节点的指针325
Token_Type token_tmp; //当前记号326

327
enter("Expression");328
left = Term(); //分析左操作数且得到其语法树329
while(token.type == PLUS || token.type == MINUS)330
{331
token_tmp = token.type;332
MatchToken(token_tmp);333
right = Term(); //分析右操作数且得到其语法树334
left = MakeExprNode(token_tmp, left, right); 335
//构造运算的语法树, 结果为左子树336
}337
Tree_trace(left); //打印表达式的语法树338
back("Expression");339
return left; //返回最终表达式的语法树340
}341

342
// -------------Term的递归子程序343
static struct ExprNode *Term()344
{345
struct ExprNode *left, *right;346
Token_Type token_tmp;347

348
left = Factor();349
while(token.type == MUL || token.type == DIV)350
{351
token_tmp = token.type;352
MatchToken(token_tmp);353
right = Factor();354
left = MakeExprNode(token_tmp, left, right);355
}356
return left;357
}358

359
// -------------Factor的递归子程序360
static struct ExprNode * Factor()361
{362
struct ExprNode *left, *right;363

364
if(token.type == PLUS) //匹配一元加运算365
{366
MatchToken(PLUS);367
right = Factor(); //表达式退化为仅有右操作数的表达式368
}369
else if(token.type == MINUS) //匹配一元减运算370
{371
MatchToken(MINUS); //表达式转化为二元减运算的表达式372
right = Factor();373
left = new ExprNode;374
left->OpCode = CONST_ID;375
left->Content.CaseConst = 0.0;376
right = MakeExprNode(MINUS, left, right);377
}378
else right = Component(); //匹配非终结符Component379

380
return right;381
}382

383
// -------------Comoenent的递归子程序384
static struct ExprNode *Component()385
{386
struct ExprNode *left, *right;387

388
left = Atom();389
if(token.type == POWER)390
{391
MatchToken(POWER);392
right = Component(); //递归调用Component以实现POWER的右集合393
left = MakeExprNode(POWER, left, right);394
}395
return left;396
}397

398
// -------------Atom的递归子程序399
static struct ExprNode *Atom()400
{401
struct Token t = token;402
struct ExprNode *address, *tmp;403

404
switch(token.type)405
{406
case CONST_ID :407
MatchToken(CONST_ID);408
address = MakeExprNode(CONST_ID, t.value);409
break;410
case T :411
MatchToken(T);412
address = MakeExprNode(T);413
break;414
case FUNC :415
MatchToken(FUNC);416
MatchToken(L_BRACKET);417
tmp = Expression();418
address = MakeExprNode(FUNC, t.FuncPtr, tmp);419
MatchToken(R_BRACKET);420
break;421
case L_BRACKET :422
MatchToken(L_BRACKET);423
address = Expression();424
MatchToken(R_BRACKET);425
break;426
default :427
SyntaxError(2);428
}429
return address;430
}431

432

433
// -------------生成语法树的一个结点434
static struct ExprNode *MakeExprNode(enum Token_Type opcode,
)435
{436
struct ExprNode *ExprPtr = new (struct ExprNode);437
ExprPtr->OpCode = opcode; //接收记号的种类438
va_list ArgPtr;439
va_start(ArgPtr, opcode);440
switch(opcode) //根据记号的类别构造不同的节点441
{442
case CONST_ID : //常数节点443
ExprPtr->Content.CaseConst = (double)va_arg(ArgPtr, double);444
break;445
case T : //参数节点446
ExprPtr->Content.CaseParmPtr = &Parameter;447
break;448
case FUNC : //函数调用节点449
ExprPtr->Content.CaseFunc.MathFuncPtr = (FuncPtr)va_arg(ArgPtr, FuncPtr);450
ExprPtr->Content.CaseFunc.Child = (struct ExprNode *)va_arg(ArgPtr, struct ExprNode *);451
break;452
default :453
ExprPtr->Content.CaseOperator.Left = (struct ExprNode *)va_arg(ArgPtr, struct ExprNode *);454
ExprPtr->Content.CaseOperator.Right = (struct ExprNode *)va_arg(ArgPtr, struct ExprNode *);455
break;456
}457
va_end(ArgPtr);458

459
return ExprPtr;460
} 1
//----------------------------parsermain.cpp-----------------------
2
3
#include <stdio.h>
4
#include "parser.h"
5
6
extern void Parser(char *SrcFilePtr);
7
8
int main()
9
{
10
Parser("test.txt");
11
return 0;
12
}
//----------------------------parsermain.cpp-----------------------2

3
#include <stdio.h>4
#include "parser.h"5

6
extern void Parser(char *SrcFilePtr);7

8
int main()9
{10
Parser("test.txt");11
return 0;12
}注:要想正常运行需要把词法分析器的那部分也加入到工程中
