编译原理课设

别的不多说 直接上代码

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
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <stdlib.h>
//创建两个char数组 和一个char变量
char prog[80],token[8],ch;
//创建五个int型的变量
int syn,p,m,n,sum;
//创建一个指针数组 里面有6个char类型的指针
char *rwtab[6]= {"begin","if","then","while","do","end"};
//定义一个处理字符的方法
scaner();
//主方法
main() {
//main方法的局部变量 在输入字符时会用到
p=0;
printf("\n please input a string(end with '#'):\r\n");
//让你输入字符 判断是不是以#结尾 没有#号则一直等待输入
do {
scanf("%c",&ch);
prog[p++]=ch;
} while(ch!='#');
//将p置为0 在scanner()方法中会用到
p=0;
do {
scaner();
//syn是从scanner中得到的 syn是定义在main方法外的全局变量 经过scanner()后被修改
switch(syn) {
case 11:
//d表示输出的是整型数字-10代表共有十个字符的宽度,不够的右面空格补齐
//5代表五个字符宽度,不够的左边空格补齐
printf("( %-10d%5d )\n",sum,syn);
break;
case -1:
printf("you have input a wrong string\n");
getch();
exit(0);
default:
//s表示输出的字符串
printf("( %-10s%5d )\n",token,syn);
break;
}
} while(syn!=0);
getch();
}
//主方法结束
//实现scanner()方法
scaner() {
sum=0;
//初始化数组
for(m=0; m<8; m++)token[m++]=NULL;
//这里是把prog[0]赋值给ch
ch=prog[p++];
m=0;
//当ch为空格 或者为换行的时候将prog[x]赋值给ch,当一直有空格和换行就一直进行赋值判断,直到找到非空格或非回车
while((ch==' ')||(ch=='\n'))
ch=prog[p++];
//a~z 97~112 A~Z 65~90 0~9 48~57 找到一个字母进入下面的if语句
if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))) {
//while循环 是大写字母或小写字母或数字都会进入循环,应该是考虑到变量的命名规则可以英文数字组合,数字开头的不可以.
while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))||((ch>='0')&&(ch<='9'))) {
token[m++]=ch;
ch=prog[p++];
}
//判断后不满足条件 则p--让别if语句做判断
p--;
syn=10;
//下面的for循环是判断这个token中的字符串是不是预定义的关键字
for(n=0; n<6; n++)
if(strcmp(token,rwtab[n])==0) {
syn=n+1;
break;
}
//下面的if语句是判断是不是数字
} else if((ch>='0')&&(ch<='9')) {
while((ch>='0')&&(ch<='9')) {
//这个sum是将我们输入的字符串中的数字打印出来
sum=sum*10+ch-'0';
ch=prog[p++];
}
p--;
syn=11;
} else switch(ch) {
//case是判断符号的 这个case是判断< 和 <=的
case '<':
token[m++]=ch;
ch=prog[p++];
if(ch=='=') {
syn=22;
token[m++]=ch;
} else {
syn=20;
p--;
}
break;
case '>':
token[m++]=ch;
ch=prog[p++];
if(ch=='=') {
syn=24;
token[m++]=ch;
} else {
syn=23;
p--;
}
break;
case '+':
token[m++]=ch;
ch=prog[p++];
if(ch=='+') {
syn=17;
token[m++]=ch;
} else {
syn=13;
p--;
}
break;

case '-':
token[m++]=ch;
ch=prog[p++];
if(ch=='-') {
syn=29;
token[m++]=ch;
} else {
syn=14;
p--;
}
break;

case '!':
ch=prog[p++];
if(ch=='=') {
syn=21;
token[m++]=ch;
} else {
syn=31;
p--;
}
break;

case '=':
token[m++]=ch;
ch=prog[p++];
if(ch=='=') {
syn=25;
token[m++]=ch;
} else {
syn=18;
p--;
}
break;
case '*':
syn=15;
token[m++]=ch;
break;
case '/':
syn=16;
token[m++]=ch;
break;
case '(':
syn=27;
token[m++]=ch;
break;
case ')':
syn=28;
token[m++]=ch;
break;
case '{':
syn=5;
token[m++]=ch;
break;
case '}':
syn=6;
token[m++]=ch;
break;
case ';':
syn=26;
token[m++]=ch;
break;
case '\"':
syn=30;
token[m++]=ch;
break;
case '#':
syn=0;
token[m++]=ch;
break;
case ':':
syn=17;
token[m++]=ch;
break;
//如果都没有匹配上 那么syn=-1
default:
syn=-1;
break;
}
//在末尾加个空格
token[m++]='\0';
}

咦~~~~ 这是嘛呀!!!
0%