CSUFT 编译原理实验二LL文法分析

Posted lmlyzxiao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CSUFT 编译原理实验二LL文法分析相关的知识,希望对你有一定的参考价值。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <iostream>
  4 #include <stack>
  5 #include <queue>
  6 #include <map>
  7 #include <algorithm>
  8 #include <vector>
  9 
 10 using namespace std;
 11 
 12 char A[20];/*分析栈*/
 13 char B[20];/*剩余串*/
 14 char v1[20]= {\'i\',\'+\',\'*\',\'(\',\')\',\'#\'}; /*终结符  */
 15 char v2[20]= {\'E\',\'G\',\'T\',\'S\',\'F\'}; /*非终结符   */
 16 
 17 int j=0,b=0,top=0,l;/*L为输入串长度 */
 18    char x,ch;
 19     int k=1;
 20     int m,n;
 21     int flag=0,finish=0;
 22 
 23 typedef struct type/*产生式类型定义      */
 24 {
 25     char origin;/*大写字符  */
 26     char array[5];/*产生式右边字符 */
 27     int length;/*字符个数      */
 28 } type;
 29 
 30 type e,t,g,g1,s,s1,f,f1,cha;/*结构体变量  */
 31 type C[10][10];/*预测分析表      */
 32 
 33 void init()
 34 {
 35     e.origin=\'E\';
 36     strcpy(e.array,"TG");
 37     t.origin=\'T\';
 38     strcpy(t.array,"FS");
 39     g.origin=\'G\';
 40     strcpy(g.array,"+TG");
 41     g1.origin=\'G\';
 42     g1.array[0]=\'^\';
 43     s.origin=\'S\';
 44     strcpy(s.array,"*FS");
 45     s1.origin=\'S\';
 46     s1.array[0]=\'^\';
 47     f.origin=\'F\';
 48     strcpy(f.array,"(E)");
 49     f1.origin=\'F\';
 50     f1.array[0]=\'i\';
 51 
 52     for(int m=0; m<=4; m++) /*初始化分析表*/
 53         for(int n=0; n<=5; n++)
 54             C[m][n].origin=\'N\';/*全部赋为空*/
 55     /*填充分析表*/
 56     C[0][0]=e;
 57     C[0][3]=e;
 58     C[1][1]=g;
 59     C[1][4]=g1;
 60     C[1][5]=g1;
 61     C[2][0]=t;
 62     C[2][3]=t;
 63     C[3][1]=s1;
 64     C[3][2]=s;
 65     C[3][4]=C[3][5]=s1;
 66     C[4][0]=f1;
 67     C[4][3]=f;
 68 }
 69 
 70 void print()/*输出分析栈  */
 71 {
 72     int a;/*指针*/
 73     for(a=0; a<=top+1; a++)
 74         printf("%c",A[a]);
 75     printf("\\t\\t");
 76 }
 77 
 78 void print1()/*输出剩余串*/
 79 {
 80     int j;
 81     for(j=0; j<b; j++) /*输出对齐符*/
 82         printf(" ");
 83     for(j=b; j<=l; j++)
 84         printf("%c",B[j]);
 85     printf("\\t\\t\\t");
 86 }
 87 int main()
 88 {
 89     init();
 90     //测试样例反例
 91     //i+i(i+i)#
 92     //i()#
 93     //正确样例
 94     //i+i*i#
 95 
 96 
 97     do/*读入分析串*/
 98     {
 99         scanf("%c",&ch);
100         if ((ch!=\'i\') &&(ch!=\'+\') &&(ch!=\'*\')&&(ch!=\'(\')&&(ch!=\')\')&&(ch!=\'#\'))
101         {
102             printf("输入串中有非法字符\\n");
103             exit(1);
104         }
105         B[j]=ch;
106         j++;
107     }while(ch!=\'#\');
108     l=j;/*分析串长度*/
109     ch=B[0];/*当前分析字符*/
110     A[top]=\'#\';
111     A[++top]=\'E\';/*\'#\',\'E\'进栈*/
112     printf("步骤\\t\\t分析栈 \\t\\t剩余字符 \\t\\t所用产生式 \\n");
113 
114         do{
115             flag = 0;
116         if(finish) break;
117         x=A[top--];/*x为当前栈顶字符*/
118         printf("%d",k++);
119         printf("\\t\\t");
120 
121 
122 
123 
124         for( j=0; j<=5; j++) /*判断是否为终结符*/
125         {
126             if(x==v1[j])
127             {
128                 flag=1;
129                 break;
130             }
131         }
132             if(flag==1)/*如果是终结符*/
133             {
134                 if(x==\'#\')
135                 {
136                     finish=1;/*结束标记*/
137                     printf("acc!\\n");/*接受 */
138                     getchar();
139                     getchar();
140                     exit(1);
141                 }
142                 if(x==ch)
143                 {
144                     print();
145                     print1();
146                     printf("%c匹配\\n",ch);
147                     ch=B[++b];/*下一个输入字符*/
148                     flag=0;/*恢复标记*/
149                 }
150                 /*else //出错处理
151                 {
152                     print();
153                     print1();
154                     printf("%c出错\\n",ch);//输出出错终结符
155                     exit(1);
156                 }*/
157             }
158             else/*非终结符处理*/
159             {
160                 for(j=0; j<=4; j++)
161                     if(x==v2[j])
162                     {
163                         m=j;/*行号*/
164                         break;
165                     }
166                 for(j=0; j<=5; j++)
167                     if(ch==v1[j])
168                     {
169                         n=j;/*列号*/
170                         break;
171                     }
172                 cha=C[m][n];
173                 if(cha.origin!=\'N\')/*判断是否为空*/
174                 {
175                     print();
176                     print1();
177                     printf("%c->",cha.origin);/*输出产生式*/
178                     int len = strlen(cha.array); //长度是array的长度
179                     for(j=0; j<len; j++)
180                         printf("%c",cha.array[j]);
181                     printf("\\n");
182                     for(j=(len-1); j>=0; j--) /*产生式逆序入栈*/
183                         A[++top]=cha.array[j];
184                     if(A[top]==\'^\')/*为空则不进栈*/
185                         top--;
186                 }
187                 else //出错处理 调整顺序
188                 {
189                     print();
190                     print1();
191                     printf("%c出错\\n",ch);//输出出错终结符
192                     exit(1);
193                 }
194 
195             }
196 
197         }while(top!=-1); //当分析栈不为空
198 
199     return 0;
200 }
View Code

送人玫瑰手留余香。。。。

以上是关于CSUFT 编译原理实验二LL文法分析的主要内容,如果未能解决你的问题,请参考以下文章

编译原理 LL文法判别方法

编译原理 LL文法判别方法

编译原理 LL文法判别方法

如何消除文法二义性如何判断二义文法—编译原理

编译原理运行时环境—什么是活动记录 活动记录与汇编代码的关系

什么是LLLRLR文法LR分析表—编译原理