递归下降分析法

根据文法:

E→E+T|E-T|T
T→T*F| T/F|F
F→(E)|i

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<stdlib.h>
  4 char TOken[10];//分开进行比较
  5 char ch;
  6 char r1[]={"begin"};
  7 char r2[]={"if"};
  8 char r3[]={"then"};
  9 char r4[]={"while"};
 10 char r5[]={"do"};
 11 char r6[]={"end"};
 12 char r7[]={"break"};
 13 char r8[]={"case"};
 14 char r9[]={"main"};
 15 char r10[]={"l(l|d)*"};
 16 char r11[]={"dd*"};
 17 char r12[]={"="};
 18 char r13[]={"+"};
 19 char r14[]={"-"};
 20 char r15[]={"*"};
 21 char r16[]={"/"};
 22 char r17[]={":"};
 23 char r18[]={"{"};
 24 char r19[]={"}"};
 25 char r20[]={"<"};
 26 char r21[]={"!="};
 27 char r22[]={"<="};
 28 char r23[]={">"};
 29 char r24[]={">="};
 30 char r25[]={"=="};
 31 char r26[]={"("};
 32 char r27[]={")"};
 33 char r28[]={"="};
 34 char r29[]={"--"};
 35 char r30[]={"++"};
 36 char r31[]={"!"};
 37 char r32[]={":="};
 38 char r33[]={";"};
 39 char r34[]={"."};
 40 char A[10000];//输入的所有值
 41 int syn,row;
 42 int n,m,p,sum,j;
 43 static int i = 0;
 44 void scaner();
 45 void E ();
 46 void E1();
 47 void T ();
 48 void T1();
 49 void F ();
 50 int main()
 51 {
 52     row = 0 ;
 53     p = 0 ;
 54     printf("符号与种别码对照表如下:\n");
 55     printf("        单词符号         种别码          单词符号          种别码\n");
 56     printf("         begin             1                 :               17\n");
 57     printf("          if               2                 {               18\n");
 58     printf("         then              3                 }               19\n");
 59     printf("         while             4                 <               20\n");
 60     printf("          do               5                 !=              21\n");
 61     printf("         end               6                 <=              22\n");
 62     printf("         break             7                 >               23\n");
 63     printf("         case              8                 >=              24\n");
 64     printf("         main              9                 ==              25\n");
 65     printf("       l(l|d)*             10                (               26\n");
 66     printf("          dd*              11                )               27\n");
 67     printf("          =                12                =               28\n");
 68     printf("          +                13                --              29\n");
 69     printf("          -                14                ++              30\n");
 70     printf("          *                15                !               31\n");
 71     printf("          /                16                :=              32\n");
 72     printf("          @                0                 ;               33\n\n");
 73     printf(" 请输入您想转换的语句(输入@结束):\n");
 74     do{
 75         scanf("%c",&ch);
 76         A[p]=ch;
 77         p++;
 78       }while(ch!='@');/*将输入的语句分别存入数组A[]中,@出现时结束语句*/
 79       p=0;
 80       do
 81         {
 82             scaner();//进入函数进行判定
 83             switch(syn)
 84             {
 85                 case 11: printf("(%d,%d)\n",syn,sum); break;//如果是11,那么就是数字
 86                 case -2: row=row++;break;
 87                 default: printf("(%d,%s)\n",syn,TOken);break;//否则,就是变量名、关键词
 88                  }
 89         }while (syn!=0);
 90       system("pause");
 91       p=0;
 92       scaner();
 93       E();
 94       if (syn==0)
 95               printf("\n 语法正确. \n");
 96      else
 97             printf("\n  语法错误. \n");
 98 
 99 }
100 void scaner()/*分别对标示符、数字、符号进行分析*/
101 {
102     for(n=0;n<10;n++)
103         TOken[n]=0;/*每次循环完就清零*/
104         m=0;
105         sum=0;
106     ch=A[i];
107     while(ch==' '||ch=='\n')/*如果字符是空格或者回车,跳过*/
108         {
109             i++;
110             ch=A[i];
111         }
112         if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) /*如果是标示符或者变量名,循环寻找*/
113         {
114             m=0;
115             while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))/*找到一个变量名或者关键字,直到遇到空格为止*/
116             {
117                 TOken[m]=ch;m++;
118                 i++;ch=A[i];
119             }
120         TOken[m]='\0';/*将识别出来的字符和已定义的标示符作比较,输出其种别码*/
121         if(strcmp(TOken,r1)==0){syn=1;}
122             else if(strcmp(TOken,r2)==0){syn=2;}
123             else if(strcmp(TOken,r3)==0){syn=3;}
124             else if(strcmp(TOken,r4)==0){syn=4;}
125             else if(strcmp(TOken,r5)==0){syn=5;}
126             else if(strcmp(TOken,r6)==0){syn=6;}
127             else if(strcmp(TOken,r7)==0){syn=7;}
128             else if(strcmp(TOken,r8)==0){syn=8;}
129             else if(strcmp(TOken,r9)==0){syn=9;}
130 
131         else{syn=10;}
132         }
133         else if((ch>='0'&&ch<='9')) //数字
134         {
135             sum=0;
136             while((ch>='0'&&ch<='9'))
137             {
138                 sum=sum*10+ch-'0';//显示其对应数字sum
139                 i++;
140                 ch=A[i];
141             }
142             syn=11;
143         }
144         else switch(ch) //有两个的字符
145             {
146                 case'<':m=0;TOken[m]=ch;m++;
147                 i++;ch=A[i];
148                 if(ch=='=')
149                 {
150                     syn=22;//<=
151                     TOken[m]=ch;m++;i++;
152                 }
153            else{syn=20;}break;//<
154 
155                 case'>':m=0;TOken[m]=ch;m++;
156                 i++;ch=A[i];
157                 if(ch=='='){
158                     syn=24;//>=
159                     TOken[m]=ch;m++;i++;
160                 }
161             else{syn=23;}break;//>
162 
163                 case':':m=0;TOken[m]=ch;m++;
164                 i++;ch=A[i];
165                 if(ch=='=')
166                 {
167                     syn=32;//:=
168                     TOken[m]=ch;m++;i++;
169                 }
170                 else
171                     {syn=17;}break;//:
172 
173                 case'@':syn=0;TOken[0]=ch;break;
174                 case'=':syn=12;TOken[0]=ch;break;
175                 case'+':syn=13;TOken[0]=ch;break;
176                 case'-':syn=14;TOken[0]=ch;break;
177                 case'*':syn=15;TOken[0]=ch;break;
178                 case'/':syn=16;TOken[0]=ch;break;
179                 case'{':syn=18;TOken[0]=ch;break;
180                 case'}':syn=19;TOken[0]=ch;break;
181                 case'(':syn=26;TOken[0]=ch;break;
182                 case')':syn=27;TOken[0]=ch;break;
183                 case';':syn=33;TOken[0]=ch;break;
184                 case'.':syn=34;TOken[0]=ch;break;
185           //      case'\n':syn=-2;break;
186                 default: syn=-1;TOken[0]=ch;
187             }
188 }
189 /*以下函数分别对应于子模块程序*/
190 
191 void E(){
192     printf("E ");
193     T();
194     E1();
195 }
196 
197 void E1(){
198     printf("E1 ");
199        if(syn==13||syn==14){
200             scaner();
201             T();
202             E1();
203        }
204        else {
205         if (syn!=27 && syn!=0)
206             printf("\n (%d,%s)语法错误! \n",syn, TOken);
207     }
208 }
209 
210 void T(){
211     printf("T ");
212     F();
213     T1();
214 }
215 
216 void T1(){
217     printf("T1 ");
218     if(syn==15||syn==16){
219             scaner();
220             F();
221             T1();
222        }
223        else{
224             if(syn!=0&&syn!=28&&syn!=13&&syn!=14)
225             printf("\n (%d,%s)语法错误! \n",syn, TOken);
226        }
227 }
228 
229 void F(){
230     printf("F ");
231     if(syn==10||syn==11)
232     {
233         scaner();
234     }
235     else if(syn==26)
236     {
237         scaner();
238         E();
239         if(syn==27){
240             scaner();
241         }
242    else
243        printf("\n (%d,%s)语法错误! \n",syn, TOken);
244     }
245 
246 }

 

posted @ 2016-12-22 04:06  245陈蔓嘉  阅读(1258)  评论(0编辑  收藏  举报