语法分析器在词法分析器的基础上增加了递归下降分析程序,咱也不知道啥是递归下降程序,咱也不想问。
但是有程序框图和伪代码把程序跑通咱还是比较在行滴。为了便于理解,debug过程中的输出也保留了。


下面是完整代码。
1 /*
2 begin a:= 9; x:=2*3;b:=a+x end#
3 x:= a+b*c end #
4 */
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #define _KEY_WORD_END "waiting for your expanding"
9 typedef struct
10 {
11 int typenum;
12 char *word;
13 }WORD;
14 char input[255];
15 char token[255]="";
16 int p_input;
17 int p_token;
18 char ch;
19 char* rwtab[] = {"begin","if","then","while","do","end",_KEY_WORD_END};
20 WORD * scaner();
21 WORD* oneword = new WORD;
22 int syn,kk;
23 void expression();
24 void factor()
25 {
26 if(syn == 10 || syn == 11)
27 {
28 oneword = scaner();
29 syn = oneword->typenum;
30 printf("%s %d\n",oneword->word,syn);
31 }
32 else if(syn == 27)
33 {
34 oneword = scaner();
35 syn = oneword->typenum;
36 printf("%s %d\n",oneword->word,syn);
37 expression();
38 if(syn == 28)
39 {
40 oneword = scaner();
41 syn = oneword->typenum;
42 printf("%s %d\n",oneword->word,syn);
43 }
44 else{
45 printf("右括号错误\n");
46 kk = 1;
47 }
48 }
49 else
50 {
51 printf("表达式错误\n");
52 kk = 1;
53 }
54 return;
55 }
56 void term()
57 {
58 factor();
59 while(syn == 15 || syn == 16)
60 {
61 oneword = scaner();
62 syn = oneword->typenum;
63 printf("%s %d\n",oneword->word,syn);
64 factor();
65 }
66 return;
67 }
68 void expression()
69 {
70 term();
71 while(syn == 13 || syn == 14)
72 {
73 oneword = scaner();
74 syn = oneword->typenum;
75 printf("%s %d\n",oneword->word,syn);
76 term();
77 }
78 return;
79 }
80 void statement()
81 {
82 if(syn == 10)
83 {
84 oneword = scaner();
85 syn = oneword->typenum;
86 printf("%s %d\n",oneword->word,syn);
87 if(syn == 18)
88 {
89 oneword = scaner();
90 syn = oneword->typenum;
91 printf("%s %d\n",oneword->word,syn);
92 expression();
93 }
94 else{
95 printf("赋值号错误\n");
96 kk = 1;
97 }
98 }
99 else{
100 printf("语句错误\n");
101 kk = 1;
102 }
103 return;
104 }
105 void yucu()
106 {
107 statement();
108 while(syn == 26)
109 {
110 oneword = scaner();
111 syn = oneword->typenum;
112 printf("%s %d\n",oneword->word,syn);
113 statement();
114 }
115 return;
116 }
117 void Irparser()
118 {
119 if(syn == 1)
120 {
121 oneword = scaner();
122 syn = oneword->typenum;
123 printf("%s %d\n",oneword->word,syn);
124 yucu();
125
126 if(syn==6)
127 {
128 oneword = scaner();
129 syn = oneword->typenum;
130 if(syn == 0 && (kk == 0))
131 printf("success\n");
132 }
133 else{
134 if(kk != 1)
135 {
136 printf("缺少end错误\n");
137 kk = 1;
138 }
139 }
140 }
141 else{
142 printf("begin错误\n");
143 kk = 1;
144 }
145 return;
146 }
147 int main()
148 {
149 int over = 1;
150
151 printf("Enter Your words(end with #):");
152 scanf("%[^#]s",input);
153 p_input = 0;
154 printf("Your words:\n%s\n",input);
155
156 //获取下一个单词符号
157 oneword = scaner();
158 syn = oneword->typenum;
159 Irparser();
160
161 printf("\npress # to exit:");
162 scanf("%[^#]s",input);
163 return 0;
164 }
165 char m_getch()
166 {
167 ch = input[p_input];
168 p_input = p_input+1;
169 return(ch);
170 }
171 void getbc()
172 {
173 while(ch == ' '||ch == 10)
174 {
175 ch = input[p_input];
176 p_input++;
177 }
178 }
179 void concat()
180 {
181 token[p_token] = ch;
182 p_token++;
183 token[p_token] = '\0';
184 }
185 int letter()
186 {
187 if((ch >= 'a'&& ch <= 'z')|| (ch >='A'&&ch <= 'Z'))
188 return 1;
189 else
190 return 0;
191 }
192 int digit()
193 {
194 if(ch >= '0'&&ch <='9')return 1;
195 else return 0;
196 }
197 int reserve()
198 {
199 int i = 0;
200 while(strcmp(rwtab[i],_KEY_WORD_END))
201 {
202 if(!strcmp(rwtab[i],token))
203 return i+1;
204 i++;
205 }
206 return 10;
207 }
208 void retract()
209 {
210 p_input--;
211 }
212
213 char* dtb()
214 {
215 return NULL;
216 }
217
218 WORD* scaner()
219 {
220
221 WORD* myword = new WORD;
222 myword->typenum = 10;
223 myword->word = "";
224 p_token = 0;
225 m_getch();
226 getbc();
227 if(letter())
228 {
229 while(letter()||digit())
230 {
231 concat();
232 m_getch();
233 }
234 retract();
235 myword->typenum = reserve();
236 myword->word = token;
237 return(myword);
238 }
239 else if(digit())
240 {
241 while(digit())
242 {
243 concat();
244 m_getch();
245 }
246 retract();
247 myword->typenum = 11;
248 myword->word = token;
249 return(myword);
250 }
251 else switch(ch)
252 {
253 case'=':m_getch();
254 if(ch == '=')
255 {
256 myword->typenum = 25;
257 myword->word = "==";
258 return(myword);
259 }
260 retract();
261 myword->typenum = 21;
262 myword->word = "=";
263 return(myword);
264 break;
265 case'+':
266 myword->typenum = 13;
267 myword->word = "+";
268 return(myword);
269 break;
270 case'-':
271 myword->typenum = 14;
272 myword->word = "-";
273 return(myword);
274 break;
275 case'*':
276 myword->typenum = 15;
277 myword->word = "*";
278 return(myword);
279 break;
280 case'/':
281 myword->typenum = 16;
282 myword->word = "/";
283 return(myword);
284 break;
285 case'(':
286 myword->typenum = 27;
287 myword->word = "(";
288 return(myword);
289 break;
290 case')':
291 myword->typenum = 28;
292 myword->word = ")";
293 return(myword);
294 break;
295 case'[':
296 myword->typenum = 28;
297 myword->word = "[";
298 return(myword);
299 break;
300 case']':
301 myword->typenum = 29;
302 myword->word = "]";
303 return(myword);
304 break;
305 case'{':
306 myword->typenum = 30;
307 myword->word = "{";
308 return(myword);
309 break;
310 case'}':
311 myword->typenum = 31;
312 myword->word = "}";
313 return(myword);
314 break;
315 case',':
316 myword->typenum = 32;
317 myword->word = ",";
318 return(myword);
319 break;
320 case':':m_getch();
321 if(ch == '=')
322 {
323 myword->typenum = 18;
324 myword->word = ":=";
325 return(myword);
326 }
327 retract();
328 myword->typenum = 17;
329 myword->word = ":";
330 return(myword);
331 break;
332 case';':
333 myword->typenum = 26;
334 myword->word = ";";
335 return(myword);
336 break;
337 case'>':m_getch();
338 if(ch == '=')
339 {
340 myword->typenum = 24;
341 myword->word = ">=";
342 return(myword);
343 }
344 retract();
345 myword->typenum = 23;
346 myword->word = ">";
347 return(myword);
348 break;
349 case'<':m_getch();
350 if(ch == '=')
351 {
352 myword->typenum = 22;
353 myword->word = "<=";
354 return(myword);
355 }
356 else if(ch == '>')
357 {
358 myword->typenum = 21;
359 myword->word = "<>";
360 return(myword);
361 }
362 retract();
363 myword->typenum = 20;
364 myword->word = "<";
365 return(myword);
366 break;
367 case'!':m_getch();
368 if(ch == '=')
369 {
370 myword->typenum = 40;
371 myword->word = "!=";
372 return(myword);
373 }
374 retract();
375 myword->typenum = -1;
376 myword->word = "ERROR";
377 return(myword);
378 break;
379 case'#':
380 myword->typenum = 0;
381 myword->word = "#";
382 return(myword);
383 break;
384 case'\0':
385 myword->typenum = 0;
386 myword->word = "OVER";
387 return(myword);
388 break;
389 default: myword->typenum = -1;
390 myword->word = "ERROR";
391 return(myword);
392 }
393 }
来源:oschina
链接:https://my.oschina.net/u/4366482/blog/3544033