1
/*
**************************************************************\
2
*Author:Hu Wenbiao
3
*Created Time: Tue 16 Nov 2010 05:11:20 PM CST
4
*File Name: work3.cpp
5
*Description:算符优先文法
6
* 1.非终结符和终结符的编号(id)都是它们在数组中的下标
7
* 2.算法只能处理单字符的非终结符和终结符(大写字母为非终结符,
8
* 其他为终结符)
9
* 3.处理的表达式必须含有:=且其左边不能含有运算符,否则会被作为
10
* 标识符的一部分处理
11
* 4.表达式的标识符可以是字符串如:aa=bb+cc+dd*eef
12
* 5.处理表达式时先将标识符转化为i(因为文法中只用i表示标识符),
13
* 标识符的名称在NAME中记录,另外产生的中间标识符(如T1、E2)
14
* 的名称也在NAME中记录,名称的id为其下标,NAME[0]记录等号“:=”
15
* 左边的那个标识符,对于其他的标识符若id为0表示出错
16
\**************************************************************
*/
17
//
*========================*Head File*========================*\\
18
19
#include
<
stack
>
20
#include
"
work.h
"
21
22
/*
----------------------*Global Variable*----------------------
*/
23
24
N_NODE N_ARRAY[
30
];
//
非终端符数组(下标从1开始)
25
char
T_ARRAY[
30
];
//
终端符数组(下标从1开始)
26
bool
F[
30
][
30
],L[
30
][
30
];
//
F[i][j]表示id为j的终结符是否属于
27
//
id为i的非终结符的FIRSTVT,L相同。
28
stack
<
pair
<
int
,
int
>
>
S;
//
用于求FIRSTVT和LASTVT
29
char
PRECEDENCETABLE[
30
][
30
];
//
算符优先关系表
30
char
NAME[
100
][
10
];
//
用来存放标识符名称,NAME[i]表示id为i的标识符
31
int
name_foot[
100
];
//
分配中间标识符的下标,如T1中的1
32
//
*=======================*Main Program*=======================*
//
33
34
int
getTnodeId(
char
ch){
//
返回终端符编码(下标),不存在返回0
35
int
p
=
1
;
36
while
(T_ARRAY[p]
&&
T_ARRAY[p]
!=
ch) p
++
;
37
if
(T_ARRAY[p])
38
return
p;
39
else
40
return
0
;
41
}
42
43
int
getNnodeId(
char
ch){
//
返回非终端符编码(下标),不存在返回0
44
int
pos
=
1
;
45
while
(N_ARRAY[pos].val
&&
N_ARRAY[pos].val
!=
ch) pos
++
;
46
if
(N_ARRAY[pos].val)
47
return
pos;
48
else
49
return
0
;
50
}
51
52
int
getNameId(
char
*
str,
int
s,
int
t){
//
给str[s]~str[t]分配位置,并返回id
53
int
ptr
=
0
;
54
while
(NAME[ptr][
0
])ptr
++
;
55
56
for
(
int
i
=
0
;s
+
i
<=
t;i
++
)
57
NAME[ptr][i]
=
str[s
+
i];
58
59
return
ptr;
60
}
61
62
int
getNameId(
char
ch){
//
同上,重载
63
name_foot[ch]
++
;
64
int
ptr
=
0
;
65
while
(NAME[ptr][
0
])ptr
++
;
66
67
NAME[ptr][
0
]
=
ch;
68
NAME[ptr][
1
]
=
char
(name_foot[ch]
+
'
0
'
);
69
70
return
ptr;
71
}
72
73
void
insertN_ARRAY(
char
val,
char
*
str,
int
s,
int
t){
//
增加非终结符
74
int
pos
=
1
;
75
while
(N_ARRAY[pos].val
&&
N_ARRAY[pos].val
!=
val) pos
++
;
76
N_ARRAY[pos].val
=
val;
77
int
cnt
=
N_ARRAY[pos].cnt,p
=
0
;
78
for
(;s
<=
t;p
++
,s
++
){
79
N_ARRAY[pos].ARR[cnt][p]
=
str[s];
80
}
81
N_ARRAY[pos].cnt
++
;
82
}
83
84
void
insertT_ARRAY(
char
ch){
//
增加终结符
85
int
p
=
1
;
86
while
(T_ARRAY[p]) p
++
;
87
T_ARRAY[p]
=
ch;
88
}
89
90
bool
isNnode(
char
ch){
//
判断是否是非终结符
91
return
ch
>=
'
A
'
&&
ch
<=
'
Z
'
;
92
}
93
94
/*
95
* 求解所有非终结符的FIRSTVT
96
*/
97
98
void
getFIRSTVT(){
99
pair
<
int
,
int
>
cur;
//
cur.first是非终结符的id,cur.second是终结符的id
100
int
nr_Nnode
=
1
;
101
while
(N_ARRAY[nr_Nnode].val) nr_Nnode
++
;
//
其实nr_Nnode=(nr of Nnode)+1
102
for
(
int
i
=
1
;i
<
nr_Nnode;i
++
){
//
每个非终结符
103
for
(
int
j
=
0
;j
<
N_ARRAY[i].cnt;j
++
){
//
每个产生式
104
if
(
!
isNnode(N_ARRAY[i].ARR[j][
0
])){
//
N_ARRAY[i].ARR[j][0]是终结符
105
int
id_Tnode
=
getTnodeId(N_ARRAY[i].ARR[j][
0
]);
106
if
(F[i][id_Tnode])
continue
;
107
F[i][id_Tnode]
=
true
;
108
S.push(pair
<
int
,
int
>
(i,id_Tnode));
109
}
110
//
N_ARRAY[i].ARR[j][1]是终结符
111
else
if
(N_ARRAY[i].ARR[j][
1
]
&&
!
isNnode(N_ARRAY[i].ARR[j][
1
])){
112
int
id_Tnode
=
getTnodeId(N_ARRAY[i].ARR[j][
1
]);
113
if
(F[i][id_Tnode])
continue
;
114
F[i][id_Tnode]
=
true
;
115
S.push(pair
<
int
,
int
>
(i,id_Tnode));
116
}
117
}
118
}
119
while
(
!
S.empty()){
120
cur
=
S.top(),S.pop();
121
char
curNnodeVal
=
N_ARRAY[cur.first].val;
122
123
for
(
int
i
=
1
;i
<
nr_Nnode;i
++
){
124
if
(F[i][cur.second])
continue
;
//
cur.second已经属于FIRSTVT(i)
125
for
(
int
j
=
0
;j
<
N_ARRAY[i].cnt;j
++
){
//
查找哪个产生式右边以curNnodeVal为首
126
if
(N_ARRAY[i].ARR[j][
0
]
==
curNnodeVal){
127
F[i][cur.second]
=
true
;
128
S.push(pair
<
int
,
int
>
(i,cur.second));
129
break
;
130
}
131
}
132
}
133
}
134
/*
输出FIRSTVT
*/
135
for
(
int
i
=
1
;i
<
nr_Nnode;i
++
){
136
for
(
int
j
=
1
;j
<
30
;j
++
){
137
if
(F[i][j]){
138
printf(
"
FIRSTVT(%c): {
"
,N_ARRAY[i].val);
139
while
(j
<
30
){
140
if
(F[i][j])
141
printf(
"
%c
"
,T_ARRAY[j]);
142
j
++
;
143
}
144
printf(
"
}\n
"
);
145
}
146
}
147
}
148
printf(
"
\n
"
);
149
/**/
150
}
151
152
/*
153
* 求解所有非终结符的LASTVT
154
*/
155
156
void
getLASTVT(){
157
pair
<
int
,
int
>
cur;
158
int
nr_Nnode
=
1
;
159
while
(N_ARRAY[nr_Nnode].val) nr_Nnode
++
;
160
for
(
int
i
=
1
;i
<
nr_Nnode;i
++
){
161
for
(
int
j
=
0
;j
<
N_ARRAY[i].cnt;j
++
){
162
int
ptr
=
0
;
163
while
(N_ARRAY[i].ARR[j][ptr]) ptr
++
;
164
ptr
--
;
165
if
(
!
isNnode(N_ARRAY[i].ARR[j][ptr])){
166
int
id_Tnode
=
getTnodeId(N_ARRAY[i].ARR[j][ptr]);
167
if
(L[i][id_Tnode])
continue
;
168
L[i][id_Tnode]
=
true
;
169
S.push(pair
<
int
,
int
>
(i,id_Tnode));
170
}
171
else
if
(ptr
>
0
&&!
isNnode(N_ARRAY[i].ARR[j][ptr
-
1
])){
172
int
id_Tnode
=
getTnodeId(N_ARRAY[i].ARR[j][ptr
-
1
]);
173
if
(L[i][id_Tnode])
continue
;
174
L[i][id_Tnode]
=
true
;
175
S.push(pair
<
int
,
int
>
(i,id_Tnode));
176
}
177
}
178
}
179
while
(
!
S.empty()){
180
cur
=
S.top(),S.pop();
181
char
curNnodeVal
=
N_ARRAY[cur.first].val;
182
183
for
(
int
i
=
1
;i
<
nr_Nnode;i
++
){
184
for
(
int
j
=
0
;j
<
N_ARRAY[i].cnt;j
++
){
185
int
ptr
=
0
;
186
while
(N_ARRAY[i].ARR[j][ptr]) ptr
++
;
187
ptr
--
;
188
if
(N_ARRAY[i].ARR[j][ptr]
==
curNnodeVal
&&
189
!
L[i][cur.second]){
190
L[i][cur.second]
=
true
;
191
S.push(pair
<
int
,
int
>
(i,cur.second));
192
break
;
193
}
194
}
195
}
196
}
197
/*
输出LASTVT
*/
198
for
(
int
i
=
1
;i
<
nr_Nnode;i
++
){
199
for
(
int
j
=
1
;j
<
30
;j
++
){
200
if
(L[i][j]){
201
printf(
"
LASTVT(%c): {
"
,N_ARRAY[i].val);
202
while
(j
<
30
){
203
if
(L[i][j])
204
printf(
"
%c
"
,T_ARRAY[j]);
205
j
++
;
206
}
207
printf(
"
}\n
"
);
208
}
209
}
210
}
211
printf(
"
\n
"
);
212
/**/
213
}
214
215
/*
216
* 求算符优先表
217
*/
218
219
void
getPrecedenceTable(){
220
int
nr_Nnode
=
1
,nr_Tnode
=
1
;
221
while
(N_ARRAY[nr_Nnode].val) nr_Nnode
++
;
222
while
(T_ARRAY[nr_Tnode]) nr_Tnode
++
;
223
224
/*
*关于#的比较*
*/
225
int
id_sharp
=
getTnodeId(
'
#
'
);
226
for
(
int
j
=
1
;j
<
nr_Tnode;j
++
){
227
if
(F[
1
][j]){
228
PRECEDENCETABLE[id_sharp][j]
=
'
<
'
;
229
}
230
if
(L[
1
][j]){
231
PRECEDENCETABLE[j][id_sharp]
=
'
>
'
;
232
}
233
}
234
235
/*
*************
*/
236
237
for
(
int
i
=
1
;i
<
nr_Nnode;i
++
){
//
每个非终结符
238
for
(
int
j
=
0
;j
<
N_ARRAY[i].cnt;j
++
){
//
每个产生式
239
int
tail
=
0
;
240
while
(N_ARRAY[i].ARR[j][tail]) tail
++
;
241
tail
--
;
//
最后一位(非零)
242
for
(
int
p
=
0
;p
<
tail;p
++
){
243
//
tt
244
if
(
!
isNnode(N_ARRAY[i].ARR[j][p])
&&
245
!
isNnode(N_ARRAY[i].ARR[j][p
+
1
])){
246
int
id1
=
getTnodeId(N_ARRAY[i].ARR[j][p]);
247
int
id2
=
getTnodeId(N_ARRAY[i].ARR[j][p
+
1
]);
248
if
(PRECEDENCETABLE[id1][id2]){
249
printf(
"
ERROR:不是算符优先文法!
"
);
250
exit(EXIT_FAILURE);
251
}
252
PRECEDENCETABLE[id1][id2]
=
'
=
'
;
253
}
254
//
tNt
255
if
(p
<=
tail
-
2
&&!
isNnode(N_ARRAY[i].ARR[j][p])
&&
256
isNnode(N_ARRAY[i].ARR[j][p
+
1
])
&&
257
!
isNnode(N_ARRAY[i].ARR[j][p
+
2
])){
258
int
id1
=
getTnodeId(N_ARRAY[i].ARR[j][p]);
259
int
id2
=
getTnodeId(N_ARRAY[i].ARR[j][p
+
2
]);
260
if
(PRECEDENCETABLE[id1][id2]){
261
printf(
"
ERROR:不是算符优先文法!
"
);
262
exit(EXIT_FAILURE);
263
}
264
PRECEDENCETABLE[id1][id2]
=
'
=
'
;
265
}
266
//
tN
267
if
(
!
isNnode(N_ARRAY[i].ARR[j][p])
&&
268
isNnode(N_ARRAY[i].ARR[j][p
+
1
])){
269
int
id1
=
getTnodeId(N_ARRAY[i].ARR[j][p]);
270
int
id_Nnode
=
getNnodeId(N_ARRAY[i].ARR[j][p
+
1
]);
271
int
id2
=
1
;
272
while
(T_ARRAY[id2]){
273
if
(F[id_Nnode][id2]){
274
if
(PRECEDENCETABLE[id1][id2]){
275
printf(
"
ERROR:不是算符优先文法!
"
);
276
exit(EXIT_FAILURE);
277
}
278
PRECEDENCETABLE[id1][id2]
=
'
<
'
;
279
}
280
id2
++
;
281
}
282
}
283
//
Nt
284
if
(isNnode(N_ARRAY[i].ARR[j][p])
&&
285
!
isNnode(N_ARRAY[i].ARR[j][p
+
1
])){
286
int
id_Nnode
=
getNnodeId(N_ARRAY[i].ARR[j][p]);
287
int
id2
=
getTnodeId(N_ARRAY[i].ARR[j][p
+
1
]);
288
int
id1
=
1
;
289
while
(T_ARRAY[id1]){
290
if
(L[id_Nnode][id1]){
291
if
(PRECEDENCETABLE[id1][id2]){
292
printf(
"
ERROR:不是算符优先方法!
"
);
293
exit(EXIT_FAILURE);
294
}
295
PRECEDENCETABLE[id1][id2]
=
'
>
'
;
296
}
297
id1
++
;
298
}
299
}
300
}
301
}
302
}
303
//////
输出优先表
//////
//
304
cout
<<
"
"
;
305
for
(
int
i
=
1
;i
<
nr_Tnode;i
++
){
306
cout
<<
T_ARRAY[i]
<<
"
"
;
307
}
308
cout
<<
endl;
309
for
(
int
i
=
1
;i
<
nr_Tnode;i
++
){
310
cout
<<
T_ARRAY[i]
<<
"
"
;
311
for
(
int
j
=
1
;j
<
nr_Tnode;j
++
){
312
if
(PRECEDENCETABLE[i][j])
313
cout
<<
PRECEDENCETABLE[i][j]
<<
"
"
;
314
else
315
cout
<<
"
"
;
316
}
317
cout
<<
endl;
318
}
319
cout
<<
endl;
320
/////////////////////
/
321
}
322
323
/*
324
* 比较ARR[s]~ARR[t]中的id和str中的符号是否匹配
325
* 其中非终结符的id是取负值的,比较时也不比较非
326
* 终结符是否相同,只要求终结符相同,非终结符相
327
* 对应就返回true
328
*/
329
330
bool
cmpIdNodeVal(pair
<
int
,
int
>*
ARR,
int
s,
int
t,
char
*
str){
331
int
ptr
=
0
,id;
332
while
(s
<=
t
&&
str[ptr]){
333
if
(isNnode(str[ptr])){
//
非终结符
334
if
(ARR[s].first
>
0
)
335
return
false
;
336
}
337
else
if
(ARR[s].first
!=
getTnodeId(str[ptr]))
338
return
false
;
339
ptr
++
;
340
s
++
;
341
}
342
if
(s
<=
t
||
str[ptr])
343
return
false
;
344
return
true
;
345
}
346
347
/*
348
* 将STACK[s]~STACK[t]归约,返回归约后的非终结符的值,
349
* 分配并由name返回非终结符的名称id
350
*/
351
352
char
reduction(pair
<
int
,
int
>*
STACK,
int
s,
int
t,
int
&
name){
353
int
i
=
1
;
354
while
(N_ARRAY[i].val){
355
for
(
int
j
=
0
;j
<
N_ARRAY[i].cnt;j
++
){
356
if
(cmpIdNodeVal(STACK,s,t,N_ARRAY[i].ARR[j])){
//
查找成功
357
358
359
///
输出
///
360
361
if
(s
==
t
&&
STACK[s].first
>
0
){
//
1
362
name
=
STACK[s].second;
363
}
364
365
if
(s
+
1
==
t){
//
2
366
name
=
getNameId(N_ARRAY[i].val);
367
if
(STACK[s].first
>
0
){
368
printf(
"
(%c,_,%s,%s)\n
"
,
369
T_ARRAY[STACK[s].first],NAME[STACK[t].second],NAME[name]);
370
}
371
else
{
372
printf(
"
(%c,%s,_,%s)\n
"
,
373
T_ARRAY[STACK[t].first],NAME[STACK[s].second],NAME[name]);
374
}
375
}
376
if
(s
+
2
==
t){
//
3
377
if
(STACK[s].first
>
0
&&
STACK[t].first
>
0
){
//
(T)这种情况
378
name
=
STACK[s
+
1
].second;
379
}
380
else
{
381
name
=
getNameId(N_ARRAY[i].val);
382
printf(
"
(%c,%s,%s,%s)\n
"
,T_ARRAY[STACK[s
+
1
].first],
383
NAME[STACK[s].second],NAME[STACK[t].second],NAME[name]);
384
}
385
}
386
387
/////////
/
388
389
return
N_ARRAY[i].val;
390
}
391
}
392
i
++
;
393
}
394
return
0
;
395
}
396
397
/*
398
* 核心函数,处理传入的单句表达式,要求表达式必须为
399
* abc:=x*y+zuv 的形式,即必须有:=号且其左边不能有运
400
* 算符,否则会被当作标识符的一部分处理
401
*/
402
403
void
operatorPrecedenceParser(
char
*
str0){
404
///
将空格去掉
///
405
int
s
=
0
,t
=
0
,p;
406
while
(str0[t]){
407
if
(str0[t]
!=
'
'
){
408
str0[s]
=
str0[t];
409
s
++
;
410
}
411
t
++
;
412
}
413
str0[s]
=
0
;
414
415
///
将str0转换成str,由文法符号表示
///
416
char
str[
1000
];
417
int
str_name[
1000
];
//
str_name[i]是str[i]的名称,当str[i]为操作符时无意义
418
419
memset(NAME,
0
,
sizeof
(NAME));
420
memset(name_foot,
0
,
sizeof
(name_foot));
421
422
s
=
0
;
423
while
(str0[s]
&&
str0[s]
!=
'
:
'
)s
++
;
424
if
(str0[s]
==
0
){
425
printf(
"
ERROR:表达式不合法\n
"
);
426
return
;
427
}
428
getNameId(str0,
0
,s
-
1
);
//
放在NAME[0],在下面进行归约时标识符id为0时表示出错
429
s
+=
2
;
//
:=右边首字符
430
p
=
0
;
431
while
(str0[s]){
432
if
(isLetter(str0[s])){
//
标识符
433
t
=
s;
434
while
(str0[t]
&&
isLetter(str0[t]))t
++
;
435
str[p]
=
'
i
'
;
436
str_name[p]
=
getNameId(str0,s,t
-
1
);
437
s
=
t,p
++
;
438
}
439
else
{
//
操作符
440
str[p]
=
str0[s];
441
s
++
,p
++
;
442
}
443
}
444
str[p]
=
'
#
'
;
//
结束符
445
str[p
+
1
]
=
0
;
446
////////////
//
447
448
pair
<
int
,
int
>
STACK[
1000
];
//
STACK[i].first保存id,正数是Tnode,负数是Nnode
449
//
STACK[i].second保存标识符id
450
int
k
=
0
,j;STACK[k].first
=
getTnodeId(
'
#
'
);
//
STACK[k]栈顶
451
p
=
0
;
//
str[p]当前字符
452
int
q,cid;
453
454
while
(str[p]){
455
cid
=
getTnodeId(str[p]);
//
当前字符id
456
457
if
(STACK[k].first
>
0
) j
=
k;
458
else
j
=
k
-
1
;
459
460
while
(PRECEDENCETABLE[STACK[j].first][cid]
==
'
>
'
){
461
do
{
462
q
=
STACK[j].first;
463
j
=
STACK[j
-
1
].first
>
0
?
j
-
1
:j
-
2
;
464
}
while
(PRECEDENCETABLE[STACK[j].first][q]
==
'
=
'
);
465
466
int
tmp_name
=
0
;
467
char
tmp
=
reduction(STACK,j
+
1
,k,tmp_name);
//
归约
468
k
=
j
+
1
;
469
STACK[k].first
=-
getNnodeId(tmp);
470
if
(tmp_name)
471
STACK[k].second
=
tmp_name;
472
else
//
name为0表示错误
473
printf(
"
ERROR:tmp_name,when reduction
"
);
474
}
475
if
(PRECEDENCETABLE[STACK[j].first][cid]
==
'
<
'
||
476
PRECEDENCETABLE[STACK[j].first][cid]
==
'
=
'
){
477
k
++
;
478
STACK[k].first
=
cid,STACK[k].second
=
str_name[p];
479
p
++
;
480
}
481
else
{
482
if
(str[p]
==
'
#
'
&&
j
==
0
){
483
484
//
给:=左边的符号赋值
485
printf(
"
(:=,%s,_,%s)\n
"
,NAME[STACK[
1
].second],NAME[
0
]);
486
487
printf(
"
Done!\n
"
);
488
return
;
489
}
490
else
{
491
printf(
"
ERROR:归约时出错!
"
);
492
exit(
-
1
);
493
}
494
}
495
}
496
497
}
498
499
/*
500
* 读入文法
501
*/
502
503
void
readGrammar(){
504
char
str[
30
];
505
506
while
(scanf(
"
%[^\n]%*c
"
,str)
!=
EOF){
507
///
将空格去掉
///
508
int
s
=
0
,t
=
0
;
509
while
(str[t]){
510
if
(str[t]
!=
'
'
){
511
str[s]
=
str[t];
512
s
++
;
513
}
514
t
++
;
515
}
516
str[s]
=
0
;
517
////////////
//
518
519
if
(str[
0
]
<
'
A
'
||
str[
0
]
>
'
Z
'
){
//
检查首字母是否大写
520
printf(
"
ERROR:首字母不是非终结符\n
"
);
521
continue
;
522
}
523
int
p
=
0
;
524
while
(str[p]
&&
(str[p]
!=
'
-
'
||
str[p
+
1
]
!=
'
>
'
)) p
++
;
//
检查是否有符号"->"
525
if
(
!
str[p]){
526
printf(
"
ERROR:不是产生式\n
"
);
527
continue
;
528
}
529
p
+=
2
;
530
///
找终结符
///
531
t
=
p;
532
while
(str[t]){
533
if
(
!
isNnode(str[t])
&&
str[t]
!=
'
|
'
)
534
insertT_ARRAY(str[t]);
535
t
++
;
536
}
537
////////////
//
538
539
///
找产生式
///
540
while
(str[p]){
541
s
=
t
=
p;
542
while
(str[p]
&&
str[p]
!=
'
|
'
) p
++
;
543
if
(str[p]){
544
t
=
p
-
1
,p
++
;
545
}
546
else
547
t
=
p;
548
549
insertN_ARRAY(str[
0
],str,s,t);
550
}
551
////////////
//
552
}
553
insertT_ARRAY(
'
#
'
);
//
加入终结符'#'
554
}
555
556
/*
557
* 算符优先文法主函数
558
*/
559
560
void
dealOperatorPrecedenceGrammar(){
561
freopen(
"
input31
"
,
"
r
"
,stdin);
562
freopen(
"
output3
"
,
"
w
"
,stdout);
563
readGrammar();
564
getFIRSTVT();
565
getLASTVT();
566
getPrecedenceTable();
567
568
freopen(
"
input32
"
,
"
r
"
,stdin);
569
char
str[
100
];
570
while
(scanf(
"
%[^\n]%*c
"
,str)
!=
EOF){
571
operatorPrecedenceParser(str);
572
}
573
}
work.cpp
1
/*
**************************************************************\
2
*Author:Hu Wenbiao
3
*Created Time: Mon 15 Nov 2010 09:58:46 PM CST
4
*File Name: work.cpp
5
*Description:主函数
6
\**************************************************************
*/
7
//
*========================*Head File*========================*\\
8
9
#include
"
work.h
"
10
/*
----------------------*Global Variable*----------------------
*/
11
12
//
*=======================*Main Program*=======================*
//
13
14
int
main(){
15
init();
16
freopen(
"
input1
"
,
"
r
"
,stdin);
17
freopen(
"
output1
"
,
"
w
"
,stdout);
18
dealSourceCode();
19
freopen(
"
output1
"
,
"
r
"
,stdin);
20
freopen(
"
output2
"
,
"
w
"
,stdout);
21
morphologyAnalysis();
22
23
dealOperatorPrecedenceGrammar();
//
输入的设置在该函数中
24
}