1//-----------------------------parser.h---------------------------------
2#ifndef PARSER_H
3#define PARSER_H
4
5#include "scanner.h"
6
7typedef double (*FuncPtr)(double);
8struct 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
27extern void Parser(char *SrcFilePtr); // 语法分析器对外的接口
28
29#endif
2#ifndef PARSER_H
3#define PARSER_H
4
5#include "scanner.h"
6
7typedef double (*FuncPtr)(double);
8struct 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
27extern 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
44static Token token; //记号
45
46
47// ------------辅助函数声明
48static void FetchToken();
49static void MatchToken(enum Token_Type AToken);
50static void SyntaxError(int case_of);
51static void ErrMsg(unsigned LineNo, char *descrip, char *string);
52static void PrintSyntaxTree(struct ExprNode *root, int indent);
53
54// ------------非终结符的递归子程序声明
55static void Program();
56static void Statement();
57static void OriginStatement();
58static void RotStatement();
59static void ScaleStatement();
60static void ForStatement();
61static struct ExprNode *Expression();
62static struct ExprNode *Term();
63static struct ExprNode *Factor();
64static struct ExprNode *Component();
65static struct ExprNode *Atom();
66
67// -------------外部接口与语法树构造函数声明
68extern void Parser(char *SrcFilePtr);
69static struct ExprNode *MakeExprNode(enum Token_Type opcode, );
70
71// -------------通过词法分析器接口GetToken获取一个记号
72static void FetchToken()
73{
74 token = GetToken();
75 if(token.type == ERRTOKEN) SyntaxError(1);
76}
77
78// -------------匹配记号
79static void MatchToken(enum Token_Type The_Token)
80{
81 if(token.type != The_Token) SyntaxError(2);
82 FetchToken();
83}
84
85// -------------语法错误处理
86static 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// -------------打印错误信息
98void 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// -------------先序遍历并打印表达式的语法树
121void 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// -------------绘图语言解释器入口(与主程序的外部接口)
149void 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的递归子程序
165static 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的递归子程序
177static 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的递归子程序
192static 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的递归子程序
220static 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的递归子程序
248static 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的递归子程序
266static 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的递归子程序
322static 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的递归子程序
343static 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的递归子程序
360static 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的递归子程序
384static 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的递归子程序
399static 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// -------------生成语法树的一个结点
434static 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}
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
44static Token token; //记号
45
46
47// ------------辅助函数声明
48static void FetchToken();
49static void MatchToken(enum Token_Type AToken);
50static void SyntaxError(int case_of);
51static void ErrMsg(unsigned LineNo, char *descrip, char *string);
52static void PrintSyntaxTree(struct ExprNode *root, int indent);
53
54// ------------非终结符的递归子程序声明
55static void Program();
56static void Statement();
57static void OriginStatement();
58static void RotStatement();
59static void ScaleStatement();
60static void ForStatement();
61static struct ExprNode *Expression();
62static struct ExprNode *Term();
63static struct ExprNode *Factor();
64static struct ExprNode *Component();
65static struct ExprNode *Atom();
66
67// -------------外部接口与语法树构造函数声明
68extern void Parser(char *SrcFilePtr);
69static struct ExprNode *MakeExprNode(enum Token_Type opcode, );
70
71// -------------通过词法分析器接口GetToken获取一个记号
72static void FetchToken()
73{
74 token = GetToken();
75 if(token.type == ERRTOKEN) SyntaxError(1);
76}
77
78// -------------匹配记号
79static void MatchToken(enum Token_Type The_Token)
80{
81 if(token.type != The_Token) SyntaxError(2);
82 FetchToken();
83}
84
85// -------------语法错误处理
86static 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// -------------打印错误信息
98void 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// -------------先序遍历并打印表达式的语法树
121void 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// -------------绘图语言解释器入口(与主程序的外部接口)
149void 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的递归子程序
165static 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的递归子程序
177static 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的递归子程序
192static 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的递归子程序
220static 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的递归子程序
248static 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的递归子程序
266static 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的递归子程序
322static 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的递归子程序
343static 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的递归子程序
360static 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的递归子程序
384static 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的递归子程序
399static 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// -------------生成语法树的一个结点
434static 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
6extern void Parser(char *SrcFilePtr);
7
8int main()
9{
10 Parser("test.txt");
11 return 0;
12}
2
3#include <stdio.h>
4#include "parser.h"
5
6extern void Parser(char *SrcFilePtr);
7
8int main()
9{
10 Parser("test.txt");
11 return 0;
12}
注:要想正常运行需要把词法分析器的那部分也加入到工程中