![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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(" "); 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(" "); 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("输入串中有非法字符 "); 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("步骤 分析栈 剩余字符 所用产生式 "); 113 114 do{ 115 flag = 0; 116 if(finish) break; 117 x=A[top--];/*x为当前栈顶字符*/ 118 printf("%d",k++); 119 printf(" "); 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! ");/*接受 */ 138 getchar(); 139 getchar(); 140 exit(1); 141 } 142 if(x==ch) 143 { 144 print(); 145 print1(); 146 printf("%c匹配 ",ch); 147 ch=B[++b];/*下一个输入字符*/ 148 flag=0;/*恢复标记*/ 149 } 150 /*else //出错处理 151 { 152 print(); 153 print1(); 154 printf("%c出错 ",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(" "); 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出错 ",ch);//输出出错终结符 192 exit(1); 193 } 194 195 } 196 197 }while(top!=-1); //当分析栈不为空 198 199 return 0; 200 }
送人玫瑰手留余香。。。。