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

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

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
}

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

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396

397

398

399

400

401

402

403

404

405

406

407

408

409

410

411

412

413

414

415

416

417

418

419

420

421

422

423

424

425

426

427

428

429

430

431

432

433

434


435

436

437

438

439

440

441

442

443

444

445

446

447

448

449

450

451

452

453

454

455

456

457

458

459

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
}

2

3

4

5

6

7

8

9

10

11

12

注:要想正常运行需要把词法分析器的那部分也加入到工程中