zoukankan      html  css  js  c++  java
  • 编译原理预测分析程序

    直接上代码:

      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
    #
  • 相关阅读:
    Atitit RSA非对称加密原理与解决方案
    Atitit RSA非对称加密原理与解决方案
    atitit.错误:找不到或无法加载主类 的解决 v4 qa15.doc
    atitit.错误:找不到或无法加载主类 的解决 v4 qa15.doc
    Mac设置su root密码
    Window系统命令行调用控制面板程序
    Ubuntu 安装最新版nodejs
    python中time.strftime不支持中文,报错UnicodeEncodeError: 'locale' codec can't encode character 'u5e74' in position 2: encoding error
    字节跳动——IT技术工程师面试题
    HTTP状态码
  • 原文地址:https://www.cnblogs.com/eastblue/p/8877431.html
Copyright © 2011-2022 走看看