编译原理预测分析程序

直接上代码:

  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
#
posted @ 2018-04-18 20:45  东流vip  阅读(763)  评论(0编辑  收藏  举报