作业12 实验二 递归下降语法分析

一、实验目的:

利用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. 递归下降分析程序

种别码:

单词符号 种别码 单词符号 种别码
begin 1 : 17
if 2 := 18
then 3 < 20
while 4 <> 21
do 5 <= 22
end 6 > 23
I 10 >= 24
D 11 = 25
+ 13 : 26
- 14 ( 27
* 15 ) 28
/ 16 # 0
  1 #include <iostream>
  2 #include<stdio.h>
  3 #include<string.h>
  4 #include<stdlib.h>
  5 
  6 char prog[80],token[8];
  7 int syn,p,m,n,sum=0;
  8 char ch;
  9 char *rwtab[6]= {"begin","if","then","while","do","end"};
 10 void print(char *s,int n){  //词法分析的输出函数 
 11     printf("(%s,%d)
",s,n);
 12 }
 13 void scaner() {
 14     m=0;
 15     for(n=0; n<8; n++) 
 16         token[n]=NULL;
 17     ch=prog[p++];
 18     while(ch==' ')    //过滤掉空格 
 19         ch=prog[p++];
 20     if((ch>='a' && ch<='z') ||(ch>='A' && ch<='Z')) { 
 21         while((ch>='a' && ch<='z') ||(ch>='A' && ch<='Z')||(ch>='0' && ch<='9')) {
 22             token[m++]=ch;
 23             ch=prog[p++];
 24         }
 25         token[m++]='';
 26         syn=10;     //字母种别码 
 27         p=p-1;      //回退一个字符
 28         for(n=0; n<6; n++) {
 29             if(strcmp(token,rwtab[n])==0) {  //判断是否为关键字
 30                 syn=n+1;
 31                 break;
 32             }
 33         }
 34         print(token,syn);
 35     } else if(ch>='0' && ch<='9') {
 36         sum=0;
 37         while(ch>='0' && ch<='9') {
 38             sum=sum*10+ch-'0';
 39             ch=prog[p++];
 40         }
 41         p=p-1;
 42         syn=11;  //数字种别码 
 43         printf("(%d,%d)
",sum,syn);
 44     } else {
 45         switch(ch) {
 46             case '<':
 47                 m=0;
 48                 token[m++]=ch;
 49                 ch=prog[p];
 50                 if(ch=='>') {
 51                     syn=21;
 52                     token[m++]=ch;
 53                 } else if(ch=='=') {
 54                     syn=22;
 55                     token[m++]=ch;
 56                 } else {
 57                     syn=20;
 58                     p=p-1;
 59                 }
 60                 p=p+1;
 61                 token[m]='';
 62                 break;
 63             case '>':
 64                 m=0;
 65                 token[m++]=ch;
 66                 ch=prog[p++];
 67                 if(ch=='=') {
 68                     syn=24;
 69                     token[m++]=ch;
 70                 } else {
 71                     syn=23;
 72                     p=p-1;
 73                 }
 74                 break;
 75             case ':':
 76                 m=0;
 77                 token[m++]=ch;
 78                 ch=prog[p++];
 79                 if(ch=='=') {
 80                     syn=18;
 81                     token[m++]=ch;
 82                 } else {
 83                     syn=17;
 84                     p=p-1;
 85                 }
 86                 break;
 87             case '+':
 88                 syn=13;
 89                 token[0]=ch;
 90                 break;
 91             case '-':
 92                 syn=14;
 93                 token[0]=ch;
 94                 break;
 95             case '*':
 96                 syn=15;
 97                 token[0]=ch;
 98                 break;
 99             case '/':
100                 syn=16;
101                 token[0]=ch;
102                 break;
103             case ';':
104                 syn=26;
105                 token[0]=ch;
106                 break;
107             case '(':
108                 syn=27;
109                 token[0]=ch;
110                 break;
111             case ')':
112                 syn=28;
113                 token[0]=ch;
114                 break;
115             case '=':
116                 syn=25;
117                 token[0]=ch;
118                 break;
119             case '#':
120                 syn=0;
121                 token[0]=ch;
122                 break;
123             default:
124                 syn=-1;
125         }
126         print(token,syn);
127     }
128     
129 }
130 
131 void S();
132 void A();
133 void B();
134 void C();
135 void D();
136 void E();
137 int kk=0;
138  
139 void S() {
140     if (syn==1) { //begin
141         scaner();
142         A();
143         if (syn==6) { //end
144             scaner();
145             if (syn==0 && kk==0) printf("分析成功 
");
146         } else {
147             if(kk!=1) printf("语法错误,缺失 'end' ! 
");
148             kk=1;
149         }
150     } else {
151         printf("语法错误,缺失 'begin' ! 
");
152         kk=1;
153     }
154     return;
155 }
156  
157 void A() {
158     B();
159     while(syn==26) { //
160         scaner();
161         B();
162     }
163     return;
164 }
165  
166 void B() {
167     if (syn==10) { //为标识符
168         scaner();
169         if (syn==18) { //为 :=
170             scaner();
171             C();
172         } else {
173             printf("界符错误!");
174             kk=1;
175         }
176     } else {
177         printf("标识符错误!");
178         kk=1;
179     }
180     return;
181 }
182  
183  
184 void C() {
185     D();
186     while(syn==13 || syn==14) {  //+或- 
187         scaner();
188         D();
189     }
190     return;
191 }
192  
193  
194 void D() {
195     E();
196     while(syn==15 || syn==16) {  //*或/ 
197         scaner();
198         E();
199     }
200     return;
201 }
202  
203  
204 void E() {
205     if(syn==10 || syn==11)scaner(); //为标识符或整常数时,读下一个单词符号
206     else if(syn==27) {  // )
207         scaner();
208         C();
209         if(syn==28)scaner(); // ) 
210         else {
211             printf(" ')' 错误
");
212             kk=1;
213         }
214     } else {
215         printf("表达式错误
");
216         kk=1;
217     }
218     return;
219 }
220  
221  
222 int main() {
223     p=0;int i;
224     printf("********************语法分析程序***************
");
225     printf("请输入源程序:
");
226     do {
227         scanf("%c",&ch);
228         prog[p++]=ch;
229     } while(ch!='#');
230     p=0;
231     printf("词法分析为:
");
232     scaner();
233     S();
234     printf("语法分析结束!
");
235     system("pause");
236     return 0;
237 }

实验结果:

 

原文地址:https://www.cnblogs.com/m2362563619/p/11960088.html