分享SCAU编译原理实验代码

实验一:词法分析

输入:

1
2
3
4
5
begin
x:=9;
if x>0 then x:=2*x+1/3;
end
$

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
line:1  ( 1,begin)
line:2 ( 10,x)
line:2 ( 33,:)
line:2 ( 21,=)
line:2 ( 20,9)
line:2 ( 34,;)
line:3 ( 2,if)
line:3 ( 10,x)
line:3 ( 35,>)
line:3 ( 20,0)
line:3 ( 3,then)
line:3 ( 10,x)
line:3 ( 33,:)
line:3 ( 21,=)
line:3 ( 20,2)
line:3 ( 24,*)
line:3 ( 10,x)
line:3 ( 22,+)
line:3 ( 20,1)
line:3 ( 25,/)
line:3 ( 20,3)
line:3 ( 34,;)
line:4 ( 6,end)
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
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define _KEY_WORD_END "waiting for your expanding"
typedef struct {
int typenum;
char *word;
} WORD;
char input[255];
char token[255] = "";
int p_input;
int p_token;
int hang = 1;
int gang = 0;
char ch;
bool flag = true;
char *rwtab[] = {"begin", "if", "then", "while", "do", "end", _KEY_WORD_END};

WORD *scaner();

int main() {
int over = 1;
WORD *oneword = new WORD;
printf("Enter Your words(end with $):\n");
scanf("%[^$]s", input);
p_input = 0;
while (over < 1000 && over != -1) {
oneword = scaner();
if (gang == 1 && oneword->word != "/") {
printf("line:%d ( 10, /)\n", hang);
gang = 0;
flag = true;
}
if (oneword->typenum < 1000 && flag) {
//if(oneword->word == "/");
//else
printf("line:%d (% d,% s)\n", hang, oneword->typenum, oneword->word);
}
over = oneword->typenum;
}
printf("\npress $ to exit:");
scanf("% [^$]s", input);
}

char m_getchar() {
ch = input[p_input];
p_input = p_input + 1;
return (ch);
}

void getbc() {
while (ch == ' ' || ch == 10) {
if (ch == '\n') {
hang++;
flag = true;
gang = 0;
}
ch = input[p_input];
p_input = p_input + 1;
}
}

void concat() {
token[p_token] = ch;
p_token = p_token + 1;
token[p_token] = '\0';
}

int letter() {
if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch == '_')
return 1;
else
return 0;
}

int digit() {
if (ch >= '0' && ch <= '9')
return 1;
else
return 0;
}

int reserve() {
int i = 0;
while (strcmp(rwtab[i], _KEY_WORD_END)) {
if (!strcmp(rwtab[i], token))
return i + 1;
i = i + 1;
}
return 10;
}

void retract() {
p_input = p_input - 1;
}

char *dtb() {
return NULL;
}

WORD *scaner() {
WORD *myword = new WORD;
myword->typenum = 10;
myword->word = "";
p_token = 0;
m_getchar();

getbc();
if (letter()) {
while (letter() || digit()) {
concat();
m_getchar();
}
retract();
myword->typenum = reserve();
myword->word = token;
return (myword);
} else if (digit()) {
while (digit() || ch == '.') {
concat();
m_getchar();
}
retract();
myword->typenum = 20;
myword->word = token;
return (myword);
} else if (ch == '/') {
m_getchar();
if (ch == '/') { //单行注释
while (ch != '\n') { //如果不是换行
m_getchar();//一直读取下一个字符
}
flag = false;//不输出
retract();//回退字符,不然行数无法++
return (myword);
} else if (ch == '*') { //多行注释开始符号
while (1) {
m_getchar();//一直读取下一个字符
if (ch == '\n') {
hang++;//读到换行行数++
}
if (ch == '*') { //多行注释结束符号
m_getchar();
if (ch == '/') {
flag = false;//不输出
return (myword);
}
}
}
} else {
retract();
myword->typenum = 25;
myword->word = "/";
return (myword);
}
} else
switch (ch) {
case '=':
m_getchar();
if (ch == '=') {
myword->typenum = 39;
myword->word = "==";
return (myword);
}
retract();
myword->typenum = 21;
myword->word = "=";
return (myword);
break;
case '+':
myword->typenum = 22;
myword->word = "+";
return (myword);
break;
case '-':
m_getchar();
if (ch == '>') {
myword->typenum = 45;
myword->word = "->";
return (myword);
}
retract();
myword->typenum = 23;
myword->word = "-";
return (myword);
break;
case '*':
myword->typenum = 24;
myword->word = "*";
return (myword);
break;
case '/':
myword->typenum = 25;
myword->word = "/";
gang++;
if (gang == 2) {
//已有2个杠,注定是注释。
flag = false; //不输出
gang = 0;
}
return (myword);
break;
case '(':
myword->typenum = 26;
myword->word = "(";
return (myword);
break;
case ')':
myword->typenum = 27;
myword->word = ")";
return (myword);
break;
case '[':
myword->typenum = 28;
myword->word = "[";
return (myword);
break;
case ']':
myword->typenum = 29;
myword->word = "]";
return (myword);
break;
case '{':
myword->typenum = 30;
myword->word = "{";
return (myword);
break;
case '}':
myword->typenum = 31;
myword->word = "}";
return (myword);
break;
case ',':
myword->typenum = 32;
myword->word = ",";
return (myword);
break;
case ':':
myword->typenum = 33;
myword->word = ":";
return (myword);
break;
case ';':
myword->typenum = 34;
myword->word = ";";
return (myword);
break;
case '>':
m_getchar();
if (ch == '=') {
myword->typenum = 37;
myword->word = ">=";
return (myword);
}
if (ch == '>') {
myword->typenum = 46;
myword->word = ">>";
return (myword);
}
retract();
myword->typenum = 35;
myword->word = ">";
return (myword);
break;
case '<':
m_getchar();
if (ch == '=') {
myword->typenum = 38;
myword->word = "<=";
return (myword);
}
if (ch == '<') {
myword->typenum = 47;
myword->word = "<<";
return (myword);
}
retract();
myword->typenum = 36;
myword->word = "<";
return (myword);
break;
case '!':
m_getchar();
if (ch == '=') {
myword->typenum = 40;
myword->word = "!=";
return (myword);
}
retract();
myword->typenum = -1;
myword->word = "ERROR";
return (myword);
break;
case '\'':
myword->typenum = 41;
myword->word = "\'";
return (myword);
break;
case '\"':
myword->typenum = 42;
myword->word = "\"";
return (myword);
break;
case '#':
myword->typenum = 43;
myword->word = "#";
return (myword);
break;
case '.':
myword->typenum = 44;
myword->word = ".";
return (myword);
break;
case '~':
myword->typenum = 47;
myword->word = "~";
return (myword);
break;
case '\t':
myword->typenum = 999;
myword->word = "OVER";
return (myword);
break;
case '\0':
myword->typenum = 1000;
myword->word = "OVER";
return (myword);
break;
default:
myword->typenum = -1;
myword->word = "ERROR";
return (myword);
}
}

实验二:语法分析

输入:

1.正确语法

1
2
3
4
5
6
begin
a := 9;
x := 2 * 3;
b := a + x
end
#

2.任意字符后继续输入无begin

1
2
3
x := a + b * c;
end
#

3.赋值号错误

1
2
3
4
begin
x = 2;
end
#

4.加号错误

1
2
3
4
begin
b := a ++ x;
end
#

5.括号错误

1
2
3
begin
a := (x + 1;
end
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
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
461
462
463
464
465
466
467
468
469
470
471
472
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define _KEY_WORD_END "waiting for your expanding"

//结构体
typedef struct {
int typenum;
char *word;
} WORD;

//函数声明
char m_getch();

void getbc();

void concat();

int letter();

int digit();

int reserve();

void retract();

char *dtb();

WORD *scaner();

void lrparser(WORD *word);

WORD *yucu(WORD *word);

WORD *factor(WORD *word);

WORD *statement(WORD *word);

WORD *expression(WORD *word);

WORD *term(WORD *word);

char input[255];
char token[255] = "";
int p_input;
int p_token;
char ch;
int kk = 0;
char *rwtab[] = {"begin", "if", "then", "while", "do", "end", _KEY_WORD_END};

int main(void) {
printf("Enter Your words(end with #):");
int over = 1;
WORD *oneword = new WORD;//new为c++中的关键字 在使用new进行内存分配时,需要包含相关类型的头文件。#include <iostream>
while (1) //无限循环
{
printf("Enter Your words(end with #):");
scanf("%[^#]", input); //读入源程序字符串到缓冲区,以#结束,允许多行输入
p_input = 0;
printf("Your words: \n%s\n", input);
oneword = scaner();
lrparser(oneword);
while (getchar() != '\n') {
}
printf("press # to exit:");
if (getchar() == 35) {
return 0;
}
while (getchar() != '\n') {
}
}
}

// 词法分析
// 从输入缓冲区读取一个字符到ch中
char m_getch() {
ch = input[p_input];
p_input = p_input + 1;
return (ch);
}

// 去掉空白符号
void getbc() {
while (ch == ' ' || ch == 10) {
ch = input[p_input];
p_input = p_input + 1;
}
}

//拼写单词
void concat() {
token[p_token] = ch;
p_token = p_token + 1;
token[p_token] = '\0';
}

//判断是否字母
int letter() {
if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z')
return 1;
else
return 0;
}

//判断是否数字
int digit() {
if (ch >= '0' && ch <= '9')
return 1;
else
return 0;
}

// 检索关键字表格
int reserve() {
int i = 0;
while (strcmp(rwtab[i], _KEY_WORD_END)) {
if (!strcmp(rwtab[i], token)) {
return i + 1;
}
i = i + 1;
}
return 10;
}

//回退一个字符
void retract() {
p_input = p_input - 1;
}

//数字转换成二进制
char *dtb(char *buffer) {
int j = 0;
int flag = 0;
int k = (sizeof(char) << 3) - 1;

char temp = ch - '0';
for (int i = 0; i < (sizeof(char) << 3); i++, k--) {
if ((temp >> k & 0x01) == 0) {
if (flag == 1) {
buffer[j++] = 0 + '0';
}
} else {
flag = 1;
buffer[j++] = (temp >> k & 0x01) + '0';
}
}
buffer[j] = 0;
return buffer;

// Converts the ch to binary;
}

WORD *scaner() {
WORD *myword = (WORD *) malloc(sizeof(WORD));
myword->typenum = 10;
myword->word = "";
p_token = 0;
m_getch();
getbc();
if (letter()) {
while (letter() || digit()) {
concat();
m_getch();
}
retract();
myword->typenum = reserve();
myword->word = token;
return myword;
} else if (digit()) {
while (digit()) {
concat();
m_getch();
}
retract();
myword->typenum = 11;
myword->word = token;
return myword;
} else {
switch (ch) {
case '=':
m_getch();
if (ch == '=') {
myword->typenum = 39;
myword->word = "==";
return myword;
}
retract();
myword->typenum = 25;
myword->word = "=";
return myword;
break;
case '+':
myword->typenum = 13;
myword->word = "+";
return myword;
break;
case '-':
myword->typenum = 14;
myword->word = "-";
return myword;
break;
case '*':
myword->typenum = 15;
myword->word = "*";
return myword;
break;
case '/':
myword->typenum = 16;
myword->word = "/";
return myword;
break;
case '(':
myword->typenum = 27;
myword->word = "(";
return myword;
break;
case ')':
myword->typenum = 28;
myword->word = ")";
return myword;
break;
case '[':
myword->typenum = 28;
myword->word = "[";
return myword;
break;
case ']':
myword->typenum = 29;
myword->word = "]";
return myword;
break;
case '{':
myword->typenum = 30;
myword->word = "{";
return myword;
break;
case '}':
myword->typenum = 31;
myword->word = "}";
return myword;
break;
case ',':
myword->typenum = 32;
myword->word = ",";
return myword;
break;
case ':':
m_getch();
if (ch == '=') {
myword->typenum = 18;
myword->word = ":=";
return myword;
}
retract();
myword->typenum = 17;
myword->word = ":";
return myword;
break;
case ';':
myword->typenum = 26;
myword->word = ";";
return myword;
break;
case '>':
m_getch();
if (ch == '=') {
myword->typenum = 24;
myword->word = ">=";
return myword;
}
retract();
myword->typenum = 23;
myword->word = ">";
return myword;
break;
case '<':
m_getch();
if (ch == '=') {
myword->typenum = 22;
myword->word = "<=";
return myword;
} else if (ch == '>') {
myword->typenum = 21;
myword->word = "<>";
}
retract();
myword->typenum = 20;
myword->word = "<";
return myword;
break;
case '!':
m_getch();
if (ch == '=') {
myword->typenum = 40;
myword->word = "!=";
return myword;
}
retract();
myword->typenum = -1;
myword->word = "ERROR";
return myword;
break;
case '\0':
myword->typenum = 1000;
myword->word = "OVER";
return myword;
break;
default:
myword->typenum = 0;
myword->word = "#";
return myword;
}
}
}

// 语法分析 判断begin和end
void lrparser(WORD *word) {
WORD *w;
if (word == NULL) {
return;
}
if (word->typenum == 1) //种别码为1,有关键字begin
{
free(word); //释放空间
w = scaner();
w = yucu(w);
if (w == NULL) {
return;
}
if (w->typenum == 6) //种别码为6,有关键字end
{
free(w);
w = scaner();
if (w->typenum == 0 && kk == 0)
free(w);
printf("success 成功\n");
} else {
free(w);
if (kk != 1)
printf("lack END error! 错误 缺少END\n"); //缺少end
kk = 1;
}
} else {
free(word);
printf("Begin error! begin 错误\n");//无begin报错
kk = 1;
}
return;
}

//语句以;号结尾
WORD *yucu(WORD *word) {
WORD *w;
w = statement(word); //语句段分析
if (w == NULL) {
return NULL;
}
while (w->typenum == 26) //有;号
{
free(w);
w = scaner();
w = statement(w);
if (w == NULL) {
return NULL;
}
}
return w;
}

//语句段分析
WORD *statement(WORD *word) {
WORD *w;
if (word == NULL) {
return NULL;
}
if (word->typenum == 10) //字符串
{
free(word);
w = scaner();
if (w->typenum == 18) //赋值符号
{
free(w);
w = scaner();
w = expression(w); //表达式
if (w == NULL) {
return NULL;
}
return w;
} else {
free(w);
printf("assignment token error! 赋值号错误\n");
return NULL;
kk = 1;
}
} else {
free(word);
printf("statement error! 语句错误\n");
return NULL;
}
}

//表达式处理
WORD *expression(WORD *word) {
WORD *w;
w = term(word);
if (w == NULL) {
return NULL;
}
// +-法
while (w->typenum == 13 || w->typenum == 14) {
free(w);
w = scaner();
w = term(w);
if (w == NULL) {
return NULL;
}
}
return w;
}

WORD *term(WORD *word) {
WORD *w;
w = factor(word);
if (w == NULL) {
return NULL;
}
// */法
while (w->typenum == 15 || w->typenum == 16) {
free(w);
w = scaner();
w = factor(w);
if (w == NULL) {
return NULL;
}
}
return w;
}

//括号分析
WORD *factor(WORD *word) {
WORD *w;
if (word == NULL) {
return NULL;
}
if (word->typenum == 10 || word->typenum == 11) {
free(word);
w = scaner();
} else if (word->typenum == 27) {
free(word);
w = scaner();
w = expression(w);
if (w == NULL) {
return NULL;
}
if (w->typenum == 28) {
free(w);
w = scaner();
} else {
free(w);
printf(") error! ')' 错误\n");
kk = 1;
return NULL;
}
} else {
free(word);
printf("expression error! 表达式错误\n");
kk = 1;
return NULL;
}
return w;
}

实验三:语义分析

输入:

1
2
3
4
5
begin
a:=2+3*4;
x:=(a+b)/c
end
#

输出:

1
2
3
4
5
6
7
三地址指令如下:
t1=3*4
t2=2+t1
a=t2
t3=a+b
t4=t3/c
x=t4
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
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
#include<stdio.h>
#include <stdlib.h>
#include<string.h>
#include <conio.h>

// begin a:=2+3*4;x:=(a+b)/c end#
char prog[80], token[6];
int count = 0;
char ch; /*当前读入单词*/
int syn, p, m, n, sum, kk = 0, k = 0; //p/*输入缓冲区指针*/
int length = 0; //输入字符长度
int mark = 0; /*标记注释//*/
int mark2;// 用于/* */ 注释
char *rwtab[6] = {"begin", "if", "then", "while", "do", "end"};

char *expression(void);

struct {
char result[8];
char ag1[8];
char op[8];
char ag2[8];
} quad[20];

void emit(char *result, char *ag1, char *op, char *ag2) {
strcpy(quad[count].result, result);
strcpy(quad[count].ag1, ag1);
strcpy(quad[count].op, op);
strcpy(quad[count].ag2, ag2);
count++;
return;
}

/*词法扫描程序:*/
void scaner() {
for (n = 0; n < 8; n++)
token[n] = NULL;
m = 0;
ch = prog[p++];
while (ch == ' ')ch = prog[p++];
if ((ch <= 'z' && ch >= 'a') || (ch <= 'Z' && ch >= 'A')) {
while ((ch <= 'z' && ch >= 'a') || (ch <= 'Z' && ch >= 'A') || (ch <= '9' && ch >= '0')) {
token[m++] = ch;
ch = prog[p++];
}
token[m++] = '\0';
ch = prog[--p];
syn = 10;
for (n = 0; n < 6; n++)
if (strcmp(token, rwtab[n]) == 0) {
syn = n + 1;
break;
}
//break;
} else if ((ch <= '9' && ch >= '0')) {
sum = 0;
while ((ch <= '9' && ch >= '0')) {
sum = sum * 10 + ch - '0';
ch = prog[p++];
}
ch = prog[--p];
syn = 11;
} else
switch (ch) {
case '<':
m = 0;
token[m++] = ch;
ch = prog[p++];
if (ch == '>') {
syn = 21;
token[m++] = ch;
} else if (ch == '=') {
syn = 22;
token[m++] = ch;
} else {
syn = 20;
ch = prog[--p];
}
break;
case '>':
token[m++] = ch;
ch = prog[p++];
if (ch == '=') {
syn = 24;
token[m++] = ch;
} else {
syn = 23;
ch = prog[--p];
}
break;
case ':':
token[m++] = ch;
ch = prog[p++];
if (ch == '=') {
syn = 18;
token[m++] = ch;
} else {
syn = 17;
ch = prog[--p];
}
break;
case '+':
syn = 13;
token[0] = ch;
break;
case '-':
syn = 14;
token[0] = ch;
break;
case '*':
syn = 15;
token[m++] = ch;
ch = prog[p++];
if (ch == '/') {
mark2 = 1;
return scaner();
}
ch = prog[--p];
break;
case '/':
syn = 16;
token[m++] = ch;
ch = prog[p++];
if (ch == '/') {
mark = 0;
while (mark == 0) {
scaner();
}
p++;
//mark=0;
} else if (ch == '*') {
mark = 1;
syn = 30; ///**/
token[m++] = '*';
mark2 = 0;
while (mark2 == 0) {
scaner();
}
p++;
//mark2=0;
}
ch = prog[--p];
break;
case ':=':
syn = 18;
token[0] = ch;
break;
case '<>':
syn = 21;
token[0] = ch;
break;
case '<=':
syn = 22;
token[0] = ch;
break;
case '>=':
syn = 24;
token[0] = ch;
break;
case '=':
syn = 25;
token[0] = ch;
break;
case ';':
syn = 26;
token[0] = ch;
break;
case '(':
syn = 27;
token[0] = ch;
break;
case ')':
syn = 28;
token[0] = ch;
break;
case '\n':
syn = 29;
token[0] = ch;
mark = 1;
return scaner();
break;

case '#':
syn = 0;
token[0] = ch;
break;
case '\0':
syn = 1000;
token[0] = '\0';
break;
default:
syn = -1;
}
}

char *newtemp(void) {
char *p;
char m[8];
p = (char *) malloc(8);
k++;
itoa(k, m, 10);
strcpy(p + 1, m);
p[0] = 't';
return (p);
}

//factor分析函数
char *factor() {
char *fplace;
fplace = (char *) malloc(12);
strcpy(fplace, " ");
if (syn == 10) {
strcpy(fplace, token);
scaner();
} else if (syn == 11) {
itoa(sum, fplace, 10);
scaner();
} else if (syn == 27) //( 27
{
scaner();
fplace = expression();
if (syn == 28)scaner();
else {
//("缺少')' 出错!\n");
kk = 1;
}
} else {
//printf("表达式错误!\n");
kk = 1;
}
return (fplace);
}

//term分析函数
char *term(void) {
char *tp, *ep2, *eplace, *tt;
tp = (char *) malloc(12);/*分配空间*/
ep2 = (char *) malloc(12);
eplace = (char *) malloc(12);
tt = (char *) malloc(12);
strcpy(eplace, factor());
while (syn == 15 || syn == 16) {
if (syn == 15) {
tt[0] = '*';
tt[1] = '\0';
} else if (syn == 16) {
tt[0] = '/';
tt[1] = '\0';
}
scaner();
strcpy(ep2, factor());
strcpy(tp, newtemp()); //tp为临时变量
emit(tp, eplace, tt, ep2); //将三地址代码送到四元式表
strcpy(eplace, tp);
//factor();
}
return (eplace);
}

//expression表达式分析函数
char *expression() {
char *tp, *ep2, *eplace, *tt;
tp = (char *) malloc(12);/*分配空间*/
ep2 = (char *) malloc(12);
eplace = (char *) malloc(12);
tt = (char *) malloc(12);
strcpy(eplace, term());/*调用term分析产生表达式计算的第一项eplace*/
while (syn == 13 || syn == 14) {
if (syn == 13) {
tt[0] = '+';
tt[1] = '\0';
} else if (syn == 14) {
tt[0] = '-';
tt[1] = '\0';
}
scaner();
strcpy(ep2, term());/*/调用term分析产生表达式计算的第二项ep2/*/
strcpy(tp, newtemp());/*/调用newtemp产生临时变量tp存储计算结果/*/
emit(tp, eplace, tt, ep2);/*/生成四元式送入四元式表/*/
strcpy(eplace, tp);
}
return (eplace);
}

//statement语句分析函数
int statement() {
//scaner();
int schain = 0;
char tt[8], eplace[8];
if (syn == 10) {
strcpy(tt, token);
scaner();
if (syn == 18) //:= 18
{
scaner();
strcpy(eplace, expression());
emit(tt, eplace, " ", " ");
schain = 0;
//expression();
} else {
//printf("赋号值错误!\n");
kk = 1;
}
} else {
//printf("语句错误\n");
//kk=1;
}
return (schain);
}

//语句串分析
int yucu() {
int schain = 0;
schain = statement();
while (syn != 6 && p != length - 1 && syn != 0) {
if (syn != 26)
scaner();
while (syn == 26) //26==;
{
scaner();
if (syn != 0 && syn != 6) {
schain = statement();
}

}
}
return (schain);
}

//递归下降分析程序
int lrparser() {
int schain = 0;
scaner();
if (syn != 1) {

//printf("begin错误\n");
kk = 1;
} else
scaner();
schain = yucu();
if (syn == 6) {
scaner();
//if(kk==0)
//printf("sucess");
} else {

if (kk != 1)
kk = 1;
//printf("缺少end\n");

}
return (schain);
}

void readFile() {
int i = 0;
char temp[255];
/*ifstream fin("data.txt");*/
FILE *fp = fopen("data.txt", "r");
while ((temp[i] = fgetc(fp)) != EOF) {
prog[i++] = temp[i];


}
length = i;
}

int main() {
int i;
p = 0;
readFile();
printf("\nplease intput string:\n");
do {
ch = getchar();
prog[p++] = ch;
} while (ch != '#');
length = p;
//将程序保存在prog字符数组中
p = 0;
//printf("词法分析:\n");
do {
scaner();
if (syn < 1000/*&&syn!=100&&syn!=101*/) {
//printf("(%d,%s)\n",syn,token);
}
} while (syn < 1000);
//printf("\n\n");
//printf("语法分析:\n");

p = 0;
//scaner();
lrparser();

//printf("\n");
printf("\n三地址指令如下:\n");
for (i = 0; i < count; i++) {
printf("%s=", quad[i].result); //t1= //x=
printf("%s", quad[i].ag1); //a //t1
printf("%s", quad[i].op); //+
printf("%s ", quad[i].ag2); //b
printf("\n");
}
getch();
}

综合性实验

设计并实现一个一遍扫描的词法语法语义分析程序,将部分C语言的语法成分(包含赋值语句、if语句、while循环语句)翻译成三地址代码,要求有一定的出错提示和错误恢复功能。

输入:

1
2
3
4
5
6
7
// 多条简单赋值语句:
main() {
a=2; b=4;
c=c-1;
area=3.14*a*a;
s= 2*3.14*r*(h+r);
}
1
2
3
4
5
6
7
8
9
10
11
12
// if分支语句
main() {
/*我是注释*/
a = 1;
b = 2;
if(a < b){
a = a + 1;
}
if(a >= b){
b = b - 1;
}
}
1
2
3
4
5
6
7
8
9
// while赋值语句
main() {
/*我是注释*/
a = 1;
b = 10;
while (a <= b) {
a = 2 * (a + 1);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
// 赋值语句+while循环+if语句嵌套:
main{
a = 5;
b = 1;
x = 1;
while(a > b){
if (x == 1){ zc = 2 * (a + b); }
if (x == 2){ ar = a * b; }
a = a - 1;
b = b + 1;
}
}
1
2
3
4
5
6
// 语法错误样例
main( {
while(a > b){
a = a + c
}
}

单词种别编码方案:

单词符号 种别码
main 1
int 2
float 3
double 4
char 5
while 6
and 7
if 8
else 9
do 10
return 11
+ 12
- 13
* 14
/ 15
% 16
< 17
<= 18
> 19
>= 20
== 21
!= 22
= 23
( 24
) 25
{ 26
} 27
; 28
, 29
// 30
/* 31
*/ 32
END 33
letter(letter|digit)* 50
digit digit* 51

项目结构:

JAVA编写

| + data

  • data0.txt

  • data1.txt

  • data2.txt

  • data3.txt

  • data4.txt

| + src

  • Main.java

  • Pair.java

  • Quadruple.java

代码:

Main.java

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
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
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
import java.io.File;
import java.io.FileReader;
import java.io.BufferedReader;
import java.util.ArrayList;
import java.util.HashMap;

public class Main {
public static HashMap<String, Integer> symbol = new HashMap<>();
public static int row = 1;
public static Pair uWord = new Pair();

public static int nowLocate = 0;
public static String inputStr;

// c语言也支持"[","]",":",switch,case
public static void setSymbol() {
// 关键字
symbol.put("main", 1);
symbol.put("int", 2);
symbol.put("float", 3);
symbol.put("double", 4);
symbol.put("char", 5);
symbol.put("while", 6);
symbol.put("and", 7);
symbol.put("if", 8);
symbol.put("else", 9);
symbol.put("do", 10);
symbol.put("return", 11);
// 加减乘除余
symbol.put("+", 12);
symbol.put("-", 13);
symbol.put("*", 14);
symbol.put("/", 15);
symbol.put("%", 16);
//
symbol.put("<", 17);
symbol.put("<=", 18);
symbol.put(">", 19);
symbol.put(">=", 20);
symbol.put("==", 21);
symbol.put("!=", 22);
symbol.put("=", 23);
//
symbol.put("(", 24);
symbol.put(")", 25);
symbol.put("{", 26);
symbol.put("}", 27);
symbol.put(";", 28);
symbol.put(",", 29);
// 注释
symbol.put("//", 30);
symbol.put("/*", 31);
symbol.put("*/", 32);
// 单词是50, 数字是51
//结束符//symbol.put("\0",33);
}

// 去掉空白符号
static int getBlank(String inputStr, int i) {
String ch = String.valueOf(inputStr.charAt(i));
while (ch.equals(" ") || ch.getBytes()[0] == 10)// 10是换行符"\n"的ascii码
{
if (ch.getBytes()[0] == 10) {
row++;
}
i = i + 1;
ch = String.valueOf(inputStr.charAt(i));
}
return i;
}

// 判断是否字母
public static boolean isLetter(String ch) {
if ((ch.getBytes()[0] >= "a".getBytes()[0] && ch.getBytes()[0] <= "z".getBytes()[0])
|| (ch.getBytes()[0] >= "A".getBytes()[0] && ch.getBytes()[0] <= "Z".getBytes()[0]))
return true;
else
return false;
}

// 判断是否数字
public static boolean isDigit(String ch) {
if (ch.getBytes()[0] >= "0".getBytes()[0] && ch.getBytes()[0] <= "9".getBytes()[0])
return true;
else
return false;
}

// 可以一行一行把c语言读入分析,这样就知道在哪行编译出错了,而且可以处理//的注释
// 如果c语言给:String="!";,这不能把"!"当成错误输入。相当于:要先处理整个c语言程序,把双引号、//注释,/**/注释的内容都去掉,再做分析
// 回车直接去掉就好,不用当作空格处理
// 直接在这个函数里把所以键值对都找出来。用一个指向start的指针,然后substring函数,找到一个字符串,然后得到单词的种别码
// "123".substring(0,1)输出1
// 读取标识符

public static boolean scanner() {
boolean flag = true;
int start;
//for (int i = 0; i < inputStr.length();)
//{
while (flag) {
flag = false;

int i = nowLocate;
i = getBlank(inputStr, i);
start = i;
String ch = String.valueOf(inputStr.charAt(i));
i++;
if (isLetter(ch)) {
while (isLetter(ch) || isDigit(ch)) {
ch = String.valueOf(inputStr.charAt(i));
i++;
}
i--;
if (symbol.get(inputStr.substring(start, i)) != null) {
uWord.setPair(symbol.get(inputStr.substring(start, i)), inputStr.substring(start, i), row);
} else {
uWord.setPair(50, inputStr.substring(start, i), row);
}
} else if (isDigit(ch)) {
while (isDigit(ch)) {
ch = String.valueOf(inputStr.charAt(i));
i++;
}
i--;
if (ch.equals(".")) {
i++;
ch = String.valueOf(inputStr.charAt(i));
i++;
while (isDigit(ch)) {
ch = String.valueOf(inputStr.charAt(i));
i++;
}
i--;
}
if (symbol.get(inputStr.substring(start, i)) != null) {
uWord.setPair(symbol.get(inputStr.substring(start, i)), inputStr.substring(start, i), row);
} else {
uWord.setPair(51, inputStr.substring(start, i), row);
}
} else {
switch (ch) {
case "+":
uWord.setPair(symbol.get(inputStr.substring(start, i)), inputStr.substring(start, i), row);
break;
case "-":
uWord.setPair(symbol.get(inputStr.substring(start, i)), inputStr.substring(start, i), row);
break;
case "*":
uWord.setPair(symbol.get(inputStr.substring(start, i)), inputStr.substring(start, i), row);
break;
case "/":
ch = String.valueOf(inputStr.charAt(i));
i++;
if (ch.equals("/") || ch.equals("*")) {
flag = true;//因为没有给uWord取到单词,所以再来一遍
if (ch.equals("/")) {
ch = String.valueOf(inputStr.charAt(i));
i++;
while (!ch.equals("\n")) {
ch = String.valueOf(inputStr.charAt(i));
i++;
}
row++;

} else if (ch.equals("*")) {
ch = String.valueOf(inputStr.charAt(i));
i++;
while (!(ch.equals("*") && String.valueOf(inputStr.charAt(i)).equals("/"))) {
ch = String.valueOf(inputStr.charAt(i));
i++;
}
i++;
}
break;
}
i--;
uWord.setPair(symbol.get(inputStr.substring(start, i)), inputStr.substring(start, i), row);
break;
case "%":
uWord.setPair(symbol.get(inputStr.substring(start, i)), inputStr.substring(start, i), row);
break;
case "<":
ch = String.valueOf(inputStr.charAt(i));
i++;
if (ch.equals("=")) {
uWord.setPair(symbol.get(inputStr.substring(start, i)), inputStr.substring(start, i), row);
break;
}
i--;
uWord.setPair(symbol.get(inputStr.substring(start, i)), inputStr.substring(start, i), row);
break;
case ">":
ch = String.valueOf(inputStr.charAt(i));
i++;
if (ch.equals("=")) {
uWord.setPair(symbol.get(inputStr.substring(start, i)), inputStr.substring(start, i), row);
break;
}
i--;
uWord.setPair(symbol.get(inputStr.substring(start, i)), inputStr.substring(start, i), row);
break;
case "=":
ch = String.valueOf(inputStr.charAt(i));
i++;
if (ch.equals("=")) {
uWord.setPair(symbol.get(inputStr.substring(start, i)), inputStr.substring(start, i), row);
break;
}
i--;
uWord.setPair(symbol.get(inputStr.substring(start, i)), inputStr.substring(start, i), row);
break;
case "!":
ch = String.valueOf(inputStr.charAt(i));
i++;
if (ch.equals("=")) {
uWord.setPair(symbol.get(inputStr.substring(start, i)), inputStr.substring(start, i), row);
break;
} else {
System.out.println("词法分析有错,在第" + row + "行。");
flag = true;//词法有错,跳过这个词,读下一个词给外面

}

case "(":
uWord.setPair(symbol.get(inputStr.substring(start, i)), inputStr.substring(start, i), row);
break;
case ")":
uWord.setPair(symbol.get(inputStr.substring(start, i)), inputStr.substring(start, i), row);
break;
case "{":
uWord.setPair(symbol.get(inputStr.substring(start, i)), inputStr.substring(start, i), row);
break;
case "}":
uWord.setPair(symbol.get(inputStr.substring(start, i)), inputStr.substring(start, i), row);
break;
case ";":
uWord.setPair(symbol.get(inputStr.substring(start, i)), inputStr.substring(start, i), row);
break;
case ",":
uWord.setPair(symbol.get(inputStr.substring(start, i)), inputStr.substring(start, i), row);
break;

case "\0":
return true;

default:
System.out.println("词法分析有错,在第" + row + "行。");
flag = true;//词法有错,跳过这个词,读下一个词给外面


}
}
//}
nowLocate = i;
}

return true;
}

// 如果从控制台读入的话,可以用while (sc.hasNext())来实现换行后继续读入
// 从文件读入,不用一遍遍复制粘贴c语言到控制台
// 换行符是"\n",ascii码是10,结束符是"\0",ascii码是0
public static String input(String fileSrc) {
StringBuffer bf = new StringBuffer();
System.out.println("加载测试文档中...");
System.out.println("程序如下:");
try {
BufferedReader br = new BufferedReader(new FileReader(fileSrc));
String temp;
int lineNumber = 1; // 初始化行号
while ((temp = br.readLine()) != null) {
// 输出带行号的内容
System.out.println("\033[32m" + String.format("%2d", lineNumber) + "\t" + temp + "\033[0m");
lineNumber++;
bf.append(temp);
bf.append("\n");
}
br.close(); // 关闭文件流
bf.append("\0");
System.out.println("加载成功!");
} catch (Exception e) {
e.printStackTrace();
}
return new String(bf);
}

public static void parse() {
int nChain[] = new int[1]/*= {1}*/;
scanner();
match(symbol.get("main"), "main");
match(symbol.get("("), "(");
match(symbol.get(")"), ")");
statementBlock(nChain);
printQuaternion();
}

public static void printQuaternion() {
System.out.println("===========================================");
System.out.println(String.format("%-7s", " ") + String.format("%-7s", "操作码") + String.format("%-6s", "操作数1") + String.format("%-7s", "操作数2") + String.format("%-4s", "结果"));
System.out.println("===========================================");
int nLoop = 0;
for (nLoop = 1; nLoop < nNXQ; nLoop++) {
System.out.println(String.format("%2d", nLoop) + ":\t( " + String.format("%-8s", pQuad.get(nLoop).op) + "| " + String.format("%-4s", pQuad.get(nLoop).argv1) + "| " + String.format("%-4s", pQuad.get(nLoop).argv2) + "| " + String.format("%-4s", pQuad.get(nLoop).result) + ")");
}
System.out.println(String.format("%2d", nLoop) + ":\t( " + String.format("%-8s", "end") + "| " + String.format("%-4s", " ") + "| " + String.format("%-4s", " ") + "| " + String.format("%-4s", "end") + ")");
}

public static void error(String strError) {
System.out.println("语法错误。Row:" + row + /*",Column:" + nColumn + */"。" + strError);
}

public static void match(int syn, String strError) {
if (syn == uWord.getType()) {
scanner();
} else {
error(strError);
}
}

public static void statementBlock(int[] nChain) {
match(symbol.get("{"), "{");
statementSequence(nChain);
match(symbol.get("}"), "}");
}

public static void statementSequence(int[] nChain) {
statement(nChain);
while (uWord.getType() == 50 || uWord.getType() == symbol.get("if") || uWord.getType() == symbol.get("while")) {
bp(nChain[0], nNXQ);
statement(nChain);
}
bp(nChain[0], nNXQ);
}

public static void bp(int p, int t) {
int w, q = p;
while (q != 0 && q < pQuad.size()) {
if (isNumeric(pQuad.get(q).result) != false) {
w = Integer.parseInt(pQuad.get(q).result);
} else {
w = 0;
}
//w = Integer.parseInt(pQuad.get(q).result);
pQuad.get(q).result = t + "";
q = w;
}
}

public static void statement(int[] nChain) {
String strTemp, eplace;
int nChainTemp[] = new int[1]/*{1}*/;
int nWQUAD;
switch (uWord.getType()) {
case 50:
strTemp = uWord.getWord();
scanner();
match(symbol.get("="), "=");
eplace = expression();
match(symbol.get(";"), ";");
gen("=", eplace, "", strTemp);
nChain[0] = 0;
break;
case 8://symbol.get("if"):
match(symbol.get("if"), "if");
match(symbol.get("("), "(");
condition(ntc, nfc);//
bp(ntc[0], nNXQ);
match(symbol.get(")"), ")");
statementBlock(nChainTemp);
nChain[0] = merg(nChainTemp[0], nfc[0]);
break;
case 6://symbol.get("while"):
match(symbol.get("while"), "while");
nWQUAD = nNXQ;
match(symbol.get("("), "(");
condition(ntc, nfc);
int nfcInt = nfc[0];//这里加这句,是因为while里有if时,while里的nfc会被覆盖,那么下方nChain[0] = nfcInt;就得到错误的nChain[0]
bp(ntc[0], nNXQ);
match(symbol.get(")"), ")");
statementBlock(nChainTemp);
bp(nChainTemp[0], nWQUAD);
strTemp = nWQUAD + "";
gen("jump", "", "", strTemp);
nChain[0] = nfcInt;
break;
}
return;
}

private static void gen(String op, String argv1, String argv2, String result) {
Quadruple four = new Quadruple(op, argv1, argv2, result);
pQuad.add(four);
nNXQ++;
}

private static void condition(int[] etc, int[] efc) {
String opp, eplace1, eplace2;
String strTemp;
eplace1 = expression();
if (uWord.getType() >= symbol.get("<") && uWord.getType() <= symbol.get("!=")) {
if (uWord.getType() == symbol.get("<") || uWord.getType() == symbol.get(">")) {
opp = uWord.getWord();
} else {
opp = uWord.getWord();
}
scanner();
eplace2 = expression();
etc[0] = nNXQ;
efc[0] = nNXQ + 1;
strTemp = "jump" + opp;
gen(strTemp, eplace1, eplace2, "0");
gen("jump", "", "", "0");
} else {
error("关系运算符");
}
}

public static boolean isNumeric(String str) {
for (int i = str.length(); --i >= 0; ) {
if (!Character.isDigit(str.charAt(i))) {
return false;
}
}
return true;
}

private static int merg(int p1, int p2) {
int p, nResult;
if (p2 == 0) {
nResult = p1;
} else {
nResult = p = p2;
while (isNumeric(pQuad.get(p).result) != false && Integer.parseInt(pQuad.get(p).result) != 0) {
p = Integer.parseInt(pQuad.get(p).result);
pQuad.get(p).result = p1 + "";
}
}
return nResult;
}

public static String expression() {
String opp, eplace, eplace1, eplace2;
eplace1 = term();
eplace = new String(eplace1);
while (uWord.getType() == symbol.get("+") || uWord.getType() == symbol.get("-")) {
opp = uWord.getWord();
scanner();
eplace2 = term();
eplace = newtemp();
gen(opp, eplace1, eplace2, eplace);
eplace1 = eplace;
}
return eplace;
}

private static String newtemp() {
nSuffix++;
return "T" + nSuffix;
}

public static String term() {
String opp, eplace, eplace1, eplace2;
eplace = eplace1 = factor();
while (uWord.getType() == symbol.get("*") || uWord.getType() == symbol.get("/")) {
opp = uWord.getWord();
scanner();
eplace2 = factor();
eplace = newtemp();
gen(opp, eplace1, eplace2, eplace);
eplace1 = eplace;
}
return eplace;
}

public static String factor() {
String eplace = "";
if (uWord.getType() == 50 || uWord.getType() == 51) //为标识符或整常数时,读下一个单词符号
{
eplace = uWord.getWord();
scanner();
} else if (uWord.getType() == symbol.get("(")) {
match(symbol.get("("), "(");
eplace = expression();
if (uWord.getType() == symbol.get(")")) {
match(symbol.get(")"), ")");
}
}
return eplace;
}

public static ArrayList<Quadruple> pQuad = new ArrayList<>();
public static int nSuffix = 0, nNXQ = 1, ntc[] = {1}, nfc[] = {1};
public static int gnColumn, gnRow;

public static void main(String[] args) {
setSymbol();
String fileSrc = System.getProperty("user.dir") + File.separator + "data/data0.txt";
inputStr = input(fileSrc)/*+"\0"*/;
pQuad.add(new Quadruple("0", "0", "0", "0"));
parse();
}
}

Pair.java

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
public class Pair {
private int type;
private String word;
private int row;

public Pair() {
}

public Pair(int type, String word, int row) {
this.type = type;
this.word = word;
this.row = row;
}

public void setPair(int type, String word, int row){
this.type = type;
this.word = word;
this.row = row;
}

public int getType() {
return type;
}

public void setType(int type) {
this.type = type;
}

public String getWord() {
return word;
}

public void setWord(String word) {
this.word = word;
}

public int getRow() {
return row;
}

public void setRow(int row) {
this.row = row;
}

@Override
public String toString()
{
return "(" + type + "," + word + ")";
}

}

Quadruple.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Quadruple {
String op;
String argv1;
String argv2;
String result;

public Quadruple() {
}

public Quadruple(String op, String argv1, String argv2, String result) {
this.op = op;
this.argv1 = argv1;
this.argv2 = argv2;
this.result = result;
}

}