一、实验目的:
利用C语言编制递归下降分析程序,并对简单语言进行语法分析。
编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。
二、实验原理
每个非终结符都对应一个子程序。
该子程序根据下一个输入符号(SELECT集)来确定按照哪一个产生式进行处理,再根据该产生式的右端:
- 每遇到一个终结符,则判断当前读入的单词是否与该终结符相匹配,若匹配,再读取下一个单词继续分析;不匹配,则进行出错处理
- 每遇到一个非终结符,则调用相应的子程序
三、实验要求说明
输入单词串,以“#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出“error”,并指出语法错误的类型及位置。
例如:
输入begin a:=9;x:=2*3;b:=a+x end #
输出success
输入x:=a+b*c end #
输出‘end' error
四、实验步骤
1.待分析的语言的语法(参考P90)
2.将其改为文法表示,至少包含
–语句
–条件
–表达式
3. 消除其左递归
4. 提取公共左因子
5. SELECT集计算
6. LL(1)文法判断
7. 递归下降分析程序
实现源代码如下:
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4
5 char prog[]="a+b*c#",token[20]; //输入程序段,单词符号
6 char ch;
7 int syn,p,m,n,sum;//单词符号类型syn,整数sum
8 char *rwtab[6] = {"begin","if","then","while","do","end"};
9
10 void E();
11 void T();
12 void E1();
13 void T1();
14 void F();
15 void error();
16
17 void scaner(){
18 for (n=0;n<20;n++)
19 token[n]=NULL;
20 m=0;
21 sum=0;
22 ch=prog[p++];
23 while(ch==' '){ //跳过空格
24 ch=prog[p++];
25 }
26 if(ch>='a'&&ch<='z'){ //判断单词
27 while(ch>='a'&&ch<='z'){
28 token[m++]=ch;
29 ch=prog[p++];
30 }
31 syn=10;
32 p--;
33 for(n=0;n<6;n++){
34 if(strcmp(token,rwtab[n])==0){
35 syn=n+1;
36 break;
37 }
38 }
39 }
40 else{
41 if(ch>='0'&&ch<='9'){ //判断数字
42 while(ch>='0'&&ch<='9'){
43 sum=sum*10+(ch-'0');
44 ch=prog[p++];
45 }
46 syn=11;
47 p--;
48 }
49 else{
50 switch(ch){
51 case '<':
52 token[m++]=ch;
53 ch=prog[p++];
54 if(ch=='>'){ //<>
55 syn=22;
56 token[m++]=ch;
57 }
58 else if(ch=='='){ //<=
59 syn=21;
60 token[m++]=ch;
61 }
62 else{ //<
63 syn=20;
64 p--;
65 }
66 break;
67
68 case '>':
69 m=0;
70 token[m++]=ch;
71 ch=prog[p++];
72 if(ch=='='){ //>=
73 syn=24;
74 token[m++]=ch;
75 }
76 else{ //>
77 syn=23;
78 p--;
79 }
80 break;
81
82 case ':':
83 m=0;
84 token[m++]=ch;
85 ch=prog[p++];
86 if(ch=='='){ //:=
87 syn=18;
88 token[m++]=ch;
89 }
90 else{ //:
91 syn=17;
92 p--;
93 }
94 break;
95
96 case '+':syn=13;token[0]=ch;break;
97 case '-':syn=14;token[0]=ch;break;
98 case '*':syn=15;token[0]=ch;break;
99 case '/':syn=16;token[0]=ch;break;
100 case '=':syn=25;token[0]=ch;break;
101 case ';':syn=26;token[0]=ch;break;
102 case '(':syn=27;token[0]=ch;break;
103 case ')':syn=28;token[0]=ch;break;
104 case '#':syn=0;token[0]=ch;break;
105 default:syn=-1;token[0]=ch;break;
106 }
107 }
108 }
109 }
110
111 void E(){
112 T();
113 E1();
114 }
115
116
117
118 void E1(){
119 if (syn == 13){
120 scaner();
121 T();
122 E1();
123 }
124 else if(syn ==0 || syn == 28){
125
126 }
127 else
128 error();
129 }
130
131 void T(){
132 F();
133 T1();
134 }
135
136 void T1(){
137 if(syn == 15){
138 scaner();
139 F();
140 T1();
141 }
142 else if (syn == 0 || syn == 28 || syn ==13){
143
144 }
145 else
146 error();
147 }
148
149 void F(){
150 if(syn == 27){
151 scaner();
152 E();
153 if(syn == 28){
154 scaner();
155 printf("success\n");
156 }
157 else
158 error();
159 }
160 else if(syn == 11 || syn == 10){
161 scaner();
162 printf("success\n");
163 }
164 else
165 error();
166 }
167
168 void error(){
169 printf("error\n");
170 printf("\n(%s,出错!)",token);
171 }
172
173 main(){
174 scaner();
175 E();
176 }