实验二 递归下降语法分析

亡梦爱人 提交于 2019-12-05 22:58:33

一、实验目的:

利用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 }

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!