直接上代码:
1 #include<cstdio> 2 #include<iostream> 3 #include<map> 4 #include<vector> 5 #include<string> 6 #include<set> 7 #include<stack> 8 #include<algorithm> 9 #include<Windows.h> 10 using namespace std; 11 12 vector<char>VN; 13 vector<char>VT; 14 bool vis_VN[30]; 15 bool vis_VT[300]; 16 bool LL_flag=true; 17 void init_visit() 18 { 19 for(int i=0;i<26;i++) 20 vis_VN[i]=true; 21 for(int i=0;i<300;i++) 22 vis_VT[i]=true; 23 } 24 25 map<char,vector<string> >mp;//用来存文法 26 map<char,set<char> >first;//用来存first集 27 map<char,set<char> >follow;//用来存follow集 28 map<char,map<char,set<string> > >pretable;//预测分析表 29 30 bool is_VN(char x)//判断是否是非终结符 31 { 32 if(x>='A'&&x<='Z') 33 return true; 34 else 35 return false; 36 } 37 38 void fun_table(char A,string str)//预测分析表的构建 39 { 40 set<char>ans; 41 bool tbool=false; 42 for(int i=0;i<str.size();i++) 43 { 44 char ch=str[i]; 45 if( !( is_VN(ch) ) )//以终结符开头 46 { 47 if(ch !='0') 48 { 49 ans.insert(ch); 50 tbool=true; 51 } 52 break; 53 } 54 else 55 { 56 set<char>::iterator it; 57 for (it = first[ch].begin(); it != first[ch].end(); it++){ 58 if(*it!='0') 59 ans.insert(*it); 60 } 61 tbool=true; 62 for(int j=0;j<mp[ch].size();j++) 63 { 64 if(mp[ch][j]=="0") 65 tbool=false; 66 } 67 if(tbool) break; 68 } 69 } 70 if(!tbool) 71 { 72 set<char>::iterator it; 73 for (it = follow[A].begin(); it != follow[A].end(); it++){ 74 if(*it!='0') 75 ans.insert(*it); 76 } 77 } 78 set<char>::iterator it; 79 for (it = ans.begin(); it != ans.end(); it++){ 80 pretable[A][*it].insert(str); 81 } 82 } 83 84 void fun_first(char A)//处理A的first集 85 { 86 string flag=""; 87 bool empty_flag=true; 88 for(int i=0;i<mp[A].size();i++) 89 { 90 flag=mp[A][i]; 91 for(int flagi=0;flagi<flag.size();flagi++) 92 { 93 char ch=flag[flagi]; 94 if( !( is_VN(ch) ) )//以终结符开头 95 { 96 first[A].insert(ch); 97 empty_flag=false; 98 break; 99 } 100 else 101 { 102 fun_first(ch); 103 set<char>::iterator it; 104 for (it = first[ch].begin(); it != first[ch].end(); it++){ 105 if(*it!='0') 106 first[A].insert(*it); 107 } 108 bool tbool=true; 109 for(int j=0;j<mp[ch].size();j++) 110 { 111 if(mp[ch][j]=="0") 112 tbool=false; 113 } 114 if(tbool) 115 { 116 empty_flag=false; 117 break; 118 } 119 } 120 } 121 if(empty_flag) 122 first[A].insert('0'); 123 } 124 } 125 126 void fun_follow(char A)//处理A的follow集 127 { 128 for(int i=0;i<VN.size();i++) 129 { 130 char ch=VN[i]; 131 for(int j=0;j<mp[ch].size();j++) 132 { 133 string s=mp[ch][j]; 134 int k=0; 135 for(k=0;k<s.length();k++) 136 { 137 if(s[k]==A) 138 { 139 if(k==s.length()-1)//如果A可直接或间接位于ch推导式的末位 ,将ch的follow集加入到A的follow集 140 { 141 set<char>::iterator it; 142 for (it = follow[ch].begin(); it != follow[ch].end(); it++) 143 { 144 follow[A].insert(*it); 145 } 146 } 147 else 148 { 149 if(is_VN(s[k+1]))//A的下一位是非终结符 150 { 151 bool flag2=false; 152 set<char>::iterator it; 153 for (it = first[s[k+1]].begin(); it != first[s[k+1]].end(); it++){ 154 if(*it!='0') 155 follow[A].insert(*it);//将A下一位非终结符的first加入A的follow集 (除去0) 156 } 157 for(int t=0;t<mp[s[k+1]].size();t++) 158 { 159 if(mp[s[k+1]][t]=="0") 160 flag2=true; 161 } 162 if(flag2)//A下一位非终结符可推倒出0 163 s[k+1]=A; 164 } 165 else 166 { 167 follow[A].insert(s[k+1]); 168 } 169 } 170 } 171 } 172 } 173 } 174 } 175 176 void show_first_follow()//显示first集和follow集 177 { 178 cout<<"First集如下:"<<endl; 179 for(int i=0;i<VN.size();i++) 180 { 181 fun_first(VN[i]); 182 cout<<VN[i]<<": "; 183 char tch=VN[i]; 184 set<char>::iterator it; 185 for (it = first[tch].begin(); it != first[tch].end(); it++){ 186 cout<<*it<<" "; 187 } 188 cout<<endl; 189 } 190 cout<<"Follow集如下:"<<endl; 191 follow[VN[0]].insert('#'); 192 for(int i=0;i<VN.size();i++) 193 fun_follow(VN[i]); 194 for(int i=0;i<VN.size();i++) 195 { 196 fun_follow(VN[i]); 197 198 cout<<VN[i]<<": "; 199 char tch=VN[i]; 200 set<char>::iterator it; 201 for (it = follow[tch].begin(); it != follow[tch].end(); it++){ 202 cout<<*it<<" "; 203 } 204 cout<<endl; 205 } 206 } 207 208 void show_pretable()//显示预测分析表 209 { 210 cout<<"预测分析表如下:"<<endl; 211 int x=VN.size()+1,y=VT.size()+1; 212 int spaceflag=0; 213 for(int i=1;i<=2*x+1;i++) 214 { 215 for(int j=1;j<=12*y+1;j++) 216 { 217 if(i%2==1) 218 cout<<'-'; 219 else 220 { 221 if(i==2&&j%12==7&&j>12) 222 cout<<VT[j/12-1]; 223 else 224 { 225 if(j%12==1) 226 cout<<'|'; 227 else if(j==7&&i>2) 228 cout<<VN[i/2-2]; 229 else 230 { 231 if(i>3&&j>13) 232 { 233 if(j%12==3) 234 { 235 int m=i/2-2,n=j/12-1; 236 set<string>::iterator it; 237 if(!pretable[VN[m]][VT[n]].empty()) 238 { 239 spaceflag-=pretable[VN[m]][VT[n]].size()-1; 240 if(pretable[VN[m]][VT[n]].size()>1) 241 LL_flag=false; 242 } 243 for (it = pretable[VN[m]][VT[n]].begin(); it != pretable[VN[m]][VT[n]].end(); it++){ 244 cout<<*it<<" "; 245 spaceflag-=(*it).size(); 246 } 247 if(spaceflag==0) 248 cout<<' '; 249 250 } 251 else 252 { 253 if(spaceflag==0) 254 cout<<' '; 255 else 256 spaceflag++; 257 } 258 } 259 else 260 cout<<' '; 261 262 } 263 } 264 265 } 266 } 267 cout<<endl; 268 } 269 270 } 271 272 string stackstr,teststr; 273 void controlling()//总控程序+过程显示+错误处理 274 { 275 cout<<"Please input a string:"<<endl; 276 string checkstr; 277 stack<char>checkstack; 278 checkstack.push('#'); 279 checkstack.push(VN[0]); 280 stackstr="#"; 281 stackstr+=VN[0]; 282 getchar(); 283 cin>>checkstr; 284 checkstr+='#'; 285 teststr=checkstr; 286 bool strflag=true; 287 int where; 288 for(int i=0;i<checkstr.size();i++) 289 { 290 if(checkstack.top()!='0') 291 { 292 cout<<stackstr; 293 for(int j=1;j<=20-stackstr.length();j++) 294 cout<<" "; 295 cout<<checkstr[i]<<" "; 296 for(int j=i+1;j<checkstr.size();j++) 297 cout<<checkstr[j]; 298 cout<<endl; 299 } 300 301 302 if(checkstack.empty()) 303 { 304 strflag=false; 305 where=i; 306 break; 307 } 308 char ch1=checkstack.top(),ch2=checkstr[i]; 309 checkstack.pop(); 310 if(ch1=='0') 311 { 312 i--; 313 continue; 314 } 315 if(!is_VN(ch1)) 316 { 317 if(ch1!=ch2) 318 { 319 strflag=false; 320 where=i; 321 break; 322 } 323 stackstr.erase(stackstr.end()-1,stackstr.end()) ; 324 } 325 else 326 { 327 if(pretable[ch1][ch2].empty()) 328 { 329 strflag=false; 330 where=i; 331 break; 332 } 333 else 334 { 335 stackstr.erase(stackstr.end()-1,stackstr.end()) ; 336 set<string>::iterator it; 337 it=pretable[ch1][ch2].begin(); 338 string s=*it; 339 for(int j=s.length()-1;j>=0;j--) 340 { 341 checkstack.push(s[j]); 342 if(s[j]!='0') 343 stackstr+=s[j]; 344 } 345 i--; 346 } 347 } 348 } 349 if(strflag) 350 cout<<"ok"; 351 else 352 { 353 cout<<"error near column "<<where+1<<endl; 354 for(int i=0;i<checkstr.length()-1;i++) 355 { 356 if(i==where) 357 { 358 HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); 359 WORD wOldColorAttrs; 360 CONSOLE_SCREEN_BUFFER_INFO csbiInfo; 361 362 // Save the current color 363 GetConsoleScreenBufferInfo(h, &csbiInfo); 364 wOldColorAttrs = csbiInfo.wAttributes; 365 366 // Set the new color 367 SetConsoleTextAttribute(h, FOREGROUND_RED | FOREGROUND_INTENSITY | BACKGROUND_GREEN); 368 cout<<checkstr[i]; 369 SetConsoleTextAttribute(h, wOldColorAttrs); 370 continue; 371 372 } 373 cout<<checkstr[i]; 374 } 375 if(where==checkstr.length()-1) 376 { 377 HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); 378 WORD wOldColorAttrs; 379 CONSOLE_SCREEN_BUFFER_INFO csbiInfo; 380 381 // Save the current color 382 GetConsoleScreenBufferInfo(h, &csbiInfo); 383 wOldColorAttrs = csbiInfo.wAttributes; 384 385 // Set the new color 386 SetConsoleTextAttribute(h, FOREGROUND_RED | FOREGROUND_INTENSITY | BACKGROUND_GREEN); 387 cout<<'?'; 388 SetConsoleTextAttribute(h, wOldColorAttrs); 389 } 390 } 391 } 392 393 int main() 394 { 395 init_visit(); 396 int k=1; 397 char vn; 398 string str; 399 while(cin>>vn&&vn!='#'&&cin>>str) 400 { 401 if(vis_VN[vn-'A']==true)//不重复存vn 402 { 403 VN.push_back(vn); 404 vis_VN[vn-'A']=false; 405 } 406 mp[vn].push_back(str);//代表vn可以推导出str 407 for(int i=0;i<str.size();i++) 408 { 409 if(!is_VN(str[i])&&vis_VT[(int)str[i]]==true&&str[i]!='0') 410 { 411 VT.push_back(str[i]); 412 vis_VT[(int)str[i]]=false; 413 } 414 } 415 416 } 417 VT.push_back('#'); 418 sort(VT.begin(),VT.end()-1); 419 show_first_follow(); 420 for(int i=0;i<VN.size();i++)//构建预测分析表 421 { 422 for(int j=0;j<mp[VN[i]].size();j++) 423 { 424 fun_table(VN[i],mp[VN[i]][j]); 425 } 426 } 427 show_pretable(); 428 if(LL_flag) 429 cout<<"This is a LL(1)"<<endl; 430 else 431 { 432 cout<<"This is not a LL(1)"<<endl; 433 return 0; 434 } 435 while(1) 436 { 437 controlling(); 438 cout<<endl; 439 } 440 441 442 }
样例:
E TA A +E A 0 T FB B T B 0 F PC C *C C 0 P (E) P a P b P v # S Ab A a A b A 0 # S ABc A a A 0 B b B 0 #