對於給定的文法G[E] :
E→E+T|E-T|T
T→T*F| T/F|F
F→(E)|i
消除左遞歸后的文法是:
E→TE'
E'→+TE'|-TE'|∑
T→FT'
T'→*FT'|/FT'|∑
F→(E)|i
是否是LL(1)文法?
select(E→TE')=first(TE')={(,i}
select(E'→+TE')=first(+TE')={+}
select(E'→-TE')=first(-TE')={-}
select(E'→∑)=follow(E')={),#}
select(T→FT')=first(FT')={(,i}
select(T'→*FT')=first(*FT')={*}
select(T'→/FT')=first(/FT')={/}
select(T'→∑)=follow(T')={+,-,),#)
select(F→(E))=first((E))={(}
select(F→i)=first(i)={i}
由上分析,得知此文法滿足LL(1)文法
1 #include<stdio.h> 2 #include <string.h> 3 void scaner(); 4 void E(); 5 void E1(); 6 void T(); 7 void T1(); 8 void F(); 9 void error(); 10 char proce[100],ch,token[20]; 11 int syn,i,j,m,sum=0; 12 char *keyword[6]= {"begin","if","then","while","do","end"}; 13 main() 14 { 15 i=0;//記錄輸入多少個字符 16 printf("\n 請輸入詞法分析程序:"); 17 do{ 18 ch=getchar(); 19 proce[i]=ch; 20 i++; 21 }while (ch!='#'); 22 i=0; 23 do{ 24 scaner(); 25 switch(syn) 26 { 27 case 11: printf("\n(%d,%d)",syn,sum); 28 break; 29 case -1: printf("\n(%s,#)",token); 30 break; 31 default: printf("\n(%d,%s)",syn, token); 32 } 33 }while (syn!=0); 34 35 printf("\n"); 36 37 i=0; 38 39 scaner(); 40 E(); 41 if (syn==0) 42 printf("\n 語法正確. \n"); 43 else printf("\n 語法失敗. \n"); 44 45 } 46 void scaner() 47 { 48 for (j=0;j<20;j++) 49 token[j]=NULL;//將token賦值為空 50 m=0; 51 sum=0; 52 ch=proce[i]; 53 i++; 54 while (ch==' ') 55 { 56 ch=proce[i++]; 57 } 58 if (ch>='a'&& ch<='z') 59 {while (ch>='a'&& ch<='z'||ch>='0' && ch<='9') 60 { 61 token[m++]=ch; 62 ch=proce[i++];//繼續看后面的 63 } 64 65 syn=10;i--;//判斷為變量 66 for (j=0;j<6;j++) 67 if(strcmp(token,keyword[j])==0) 68 { 69 syn=j+1; 70 break; 71 }//如果有可以匹配的就為關鍵字 72 } 73 else 74 if(ch>='0' && ch<='9') 75 {while (ch>='0' && ch<='9') 76 { 77 sum=sum*10+(ch-'0'); 78 ch=proce[i]; 79 i++; 80 } 81 syn=11; 82 i--; 83 } 84 else 85 switch(ch) 86 { 87 case '<': token[m]=ch; 88 m++; 89 ch=proce[i]; 90 i++; 91 if (ch=='>') 92 { 93 syn=21; 94 token[m]=ch; 95 m++; 96 } 97 else if (ch=='=') 98 { 99 syn=22; 100 token[m]=ch; 101 m++; 102 } 103 else 104 { 105 syn=20; 106 i--; 107 } 108 break; 109 110 case '>': m=0; 111 token[m]=ch; 112 m++; 113 ch=proce[i]; 114 i++; 115 if (ch=='=') 116 { 117 syn=24; 118 token[m]=ch; 119 m++; 120 } 121 else 122 { 123 syn=23; 124 i--; 125 } 126 break; 127 case ':': m=0; 128 token[m++]=ch; 129 ch=proce[i++]; 130 if (ch=='=') 131 { 132 syn=18; 133 token[m++]=ch; 134 } 135 else 136 { 137 syn=17; 138 i--; 139 } 140 break; 141 case '+': 142 syn=13; 143 token[0]=ch; 144 break; 145 case '-': 146 syn=14; 147 token[0]=ch; 148 break; 149 case '*': 150 syn=15; 151 token[0]=ch; 152 break; 153 case '/': 154 syn=16; 155 token[0]=ch; 156 break; 157 case '=': 158 syn=25; 159 token[0]=ch; 160 break; 161 case ';': 162 syn=26; 163 token[0]=ch; 164 break; 165 case '(': 166 syn=27; 167 token[0]=ch; 168 break; 169 case ')': 170 syn=28; 171 token[0]=ch; 172 break; 173 case '#': 174 syn=0; 175 token[0]=ch; 176 break; 177 default: 178 syn=-1; 179 token[0]=ch; 180 } 181 } 182 void E() 183 { 184 printf("E "); 185 T(); 186 E1(); 187 188 } 189 void E1() 190 { 191 printf("E1 "); 192 if (syn==13) 193 { 194 scaner(); 195 T(); 196 E1(); 197 } 198 else { 199 if (syn!=28 && syn!=0) 200 error(); 201 } 202 } 203 void T() 204 { 205 printf("T "); 206 F(); 207 T1(); 208 } 209 void T1() 210 { 211 printf("T1 "); 212 if (syn==15) { 213 scaner(); 214 F(); 215 T1(); 216 } 217 else { 218 if (syn!=28 && syn!=0 && syn!=13) error(); 219 } 220 } 221 222 void F() 223 { 224 printf("F "); 225 if (syn==27) 226 { 227 scaner(); 228 E(); 229 if(syn==28) scaner(); 230 else error(); 231 } 232 else if (syn==11 || syn==10) 233 scaner(); 234 235 } 236 237 void error() 238 { 239 printf("\n (%d,%s)語法錯誤! \n",syn, token); 240 }