编译原理实习(应用预测分析法LL(1)实现语法分析)

来源:互联网 发布:java图书管理系统教程 编辑:程序博客网 时间:2024/05/16 01:41
  1 #include<iostream>  2 #include<fstream>  3 #include<iomanip>  4 #include<cstdio>  5 #include<cstring>  6 #include<algorithm>  7 #include<vector>  8 #include<string>  9 #include<set> 10 #include<queue> 11 #include<stack> 12 #include<map> 13 using namespace std; 14  15 typedef pair<char, string>PP; 16 typedef pair<char, pair<string, string> >PPP; 17  18  19 //*代表弧 20 //~代表空 21 //输入: 22 /* 23 S*MH 24 S*a 25 H*LSo 26 H*~ 27 K*dML 28 K*~ 29 L*eHf 30 M*K 31 M*bLM 32 */ 33  34  35 class Set{ 36  37 private: 38     multimap<char, string >Grammars;//文法 39     multimap<string, char >Re_Grammars; //反向映射 40     vector<PP >FIRST;  //FIRST集 41     vector<PP >FOLLOW; //FOLLOW集 42     set<char >Ok; //能推出空的非终结符的集合 43     set<char >Non_terminal; //非终结符集合 44     vector<string >Right; //产生式右部 45     vector<PPP >SELECT; //SELECT集 46     vector<char >Sentence; //要识别的句子 47  48 public: 49     Set(); 50     ~Set(); 51     bool Judge_Ok(char);  //判断一个非终结符是否能推出空 52     void Get_Ok();  //求出那些能推出空的非终结符集合 53     void First_Solve();  //求解FIRST集 54     void Show_First(); //输出FIRST集合 55     void Get_First(char, set<char>&);     //求解某个非终结符的FIRST集 56     void Follow_Solve(); //求解FOLLOW集 57     void Show_Follow(); //输出FOLLOW集 58     void Get_Follow(char, set<char>&);   //求解某个非终结符的FOLLOW集 59     void Select_Solve(); //求解SELECT集 60     void Show_Select();  //输出SELECT集 61     void Analysis();   //预测分析程序 62  63 }; 64  65 Set::Set() 66 { 67     ifstream infile; 68     infile.open("data.txt"); 69     if (!infile){ 70         cout << "can't open the file" << endl; 71         return; 72     } 73     string str; 74     while (infile >> str){ 75         char ch = str[0]; 76         string ss = ""; 77         for (int i = 2; i < (int)str.size(); i++)ss += str[i]; 78         Grammars.insert(make_pair(ch, ss)); //所给文法 79         Re_Grammars.insert(make_pair(ss, ch));  //反向映射集合 80         Right.push_back(ss); //得到右部产生式 81         for (int i = 0; i < (int)str.size(); i++){ 82             if (isupper(str[i]))Non_terminal.insert(str[i]); //求非终结符集合 83         } 84     } 85     infile.close(); 86 } 87  88 Set::~Set() 89 { 90     Grammars.clear(); 91     Re_Grammars.clear(); 92     Right.clear(); 93     Ok.clear(); 94     FIRST.clear(); 95     FOLLOW.clear(); 96     SELECT.clear(); 97     Non_terminal.clear(); 98 } 99 100 //判断一个非终结符是否能推出空101 bool Set::Judge_Ok(char ch)102 {103     if (Grammars.find(ch) == Grammars.end())return false;//如果找不到这个非终结符所能推出的符号,则返回false.104 105     multimap<char, string>::iterator iter = Grammars.find(ch);106     int Count =(int)Grammars.count(iter->first);107     for (int i = 0; i < Count; i++){108         bool flag = true;109         for (int j = 0; j < (int)iter->second.size(); j++){110             //如果是大写字母,那么就继续递归111             if (isupper(iter->second[j])){112                 //避免重复递归113                 if (iter->second[j] == ch){114                     flag = false;115                     break;116                 }117                 else if (!Judge_Ok(iter->second[j])){118                     flag = false;119                     break;120                 }121             }122             //如果不是大写字母,就判断是否是空,如果不是,则也是直接break;123             else if (iter->second[j] != '~'){124                 flag = false;125                 break;126             }127         }128         if (flag)return true; //在某个非终结符的多重集合中,只要有某个能产生空,那么这个非终结符就能推出空,返回true;129         iter++;130     }131     //如果都不能推出空,那么就返回false;132     return false;133 134 }135 136 137 //求出那些能推出空的非终结符集合138 void Set::Get_Ok()139 {140     set<char>::iterator iter;141     for (iter = Non_terminal.begin(); iter != Non_terminal.end(); iter++){142         if(Judge_Ok((*iter))){143             Ok.insert(*iter);144         }145     }146 }147 148 //求某一个非终结符的FIRST集149 void Set::Get_First(char ch, set<char>&st)150 {151     if (Grammars.find(ch) == Grammars.end())return;   //如果没有找到非终结符可以转化的符号,则直接返回152 153     multimap<char, string>::iterator iter = Grammars.find(ch);154     int Count = (int)Grammars.count(iter->first);155     for (int i = 0; i < Count; i++){156         for (int j = 0; j < (int)(iter->second.size()); j++){157             //此时碰到的是终结符,找到后将其插入到set集合中,并且立马跳出循环,找下一个158             if (!isupper(iter->second[j])){159                 st.insert(iter->second[j]);160                 break;161             }162             else if (isupper(iter->second[j])){163                 //避免重复递归164                 if (iter->second[j] == ch){165                     break;166                 }167                 //如果不重复,那么就从这个非终结符继续找168                 Get_First(iter->second[j], st);169 170                 //如果这个非终结符不能推出空,那么就直接break寻找下一个映射171                 if (Ok.find(iter->second[j]) == Ok.end()){172                     break;173                 }174             }175         }176         iter++;177     }178 }179 180 181 //求所有非终结符的FIRST集182 void Set::First_Solve()183 {184     set<char >First;185     for (set<char >::iterator iter = Non_terminal.begin(); iter != Non_terminal.end(); iter++){186         First.clear();187         Get_First(*iter, First); //求某一个非终结符的FIRST集188         string str = "";189         for (set<char>::iterator it = First.begin(); it != First.end(); it++)str += (*it);190         FIRST.push_back(make_pair(*iter, str));191     }192 }193 194 //输出FIRST集195 void Set::Show_First()196 {197     cout << "  " << "FIRST集" << " " << endl << endl;198     for (int i = 0; i <(int) FIRST.size(); i++){199         cout << FIRST[i].first << "";200         for (int j = 0; j <(int) FIRST[i].second.size(); j++){201             cout << FIRST[i].second[j] << " ";202         }203         cout << endl;204     }205     cout << endl;206 }207 208 209 //求某一个非终结符的FOLLOW集210 void Set::Get_Follow(char ch, set<char>&st)211 {212     if (ch == 'S')st.insert('#');//如果是开始符;213     for (int i = 0; i < (int)Right.size(); i++){214         string str = Right[i];215         for (int j = 0; j < (int)Right[i].size(); j++){216             //如果不是当前产生式的最后一个217             if (Right[i][j] == ch&&j !=(int) Right[i].size() - 1){218                 //如果后面紧跟着的是终结符219                 if (!isupper(Right[i][j + 1])){220                     if (Right[i][j + 1] != '~'){221                         st.insert(Right[i][j + 1]);222                     }223                 }224                 else{225                     //后面紧跟着是非终结符,就把这个非终极符的FIRST集(除了空)加入到当前ch的FOLLOW集中226                     vector<PP>::iterator iter = FIRST.begin();227                     while (iter != FIRST.end()){228                         if (iter->first == Right[i][j+1]){229                             break;230                         }231                         iter++;232                     }233                     for (int k = 0; k < (int)iter->second.size(); k++){234                         if (iter->second[k] != '~')st.insert(iter->second[k]);235                     }236                     //如果对形如“…UP”(P是非终结符的组合)的组合;237                     //如果这些非终结符都能推出空,就么就要把左部(假设是S)的Follow(S)送入到Follow(U)中238                     bool flag = true;239                     for (int pos = j + 1; pos < (int)Right[i].size(); pos++){240                         if (isupper(Right[i][pos]) && Ok.find(Right[i][pos]) != Ok.end()){241                             vector<PP>::iterator ii = FIRST.begin();242                             while (ii != FIRST.end()){243                                 if (ii->first == Right[i][pos]){244                                     break;245                                 }246                                 ii++;247                             }248                             for (int k = 0; k < (int)ii->second.size(); k++){249                                 if (ii->second[k] != '~')st.insert(ii->second[k]);250                             }251                             continue;252                         }253                         flag = false;254                         break;255                     }256                     if (flag){257                         multimap<string, char>::iterator it = Re_Grammars.find(str);258                         int Count = Re_Grammars.count(it->first);259                         while (Count--){260                             if (it->second != ch){261                                 Get_Follow(it->second, st);262                             }263                         }264                     }265                 }266             }267             //如果刚好是当前产生式的最后一个字符268             else if (Right[i][j] == ch&&j == (int)Right[i].size() - 1){269                 //反向映射找到推出str这个产生式的左部字符270                 multimap<string, char>::iterator iter = Re_Grammars.find(str);271                 int Count = Re_Grammars.count(iter->first);272                 while (Count--){273                     if (iter->second != ch){274                         Get_Follow(iter->second, st);275                     }276                 }277             }278         }279     }280 }281 282 283 //求所有非终结符的FOLLOW集284 void Set::Follow_Solve()285 {286     set<char>Follow;287     for (set<char>::iterator iter = Non_terminal.begin(); iter != Non_terminal.end(); iter++){288         Follow.clear();289         if (*iter == 'S')Follow.insert('#'); //如果是开始符290         Get_Follow(*iter, Follow);291         string str = "";292         for (set<char>::iterator it = Follow.begin(); it != Follow.end(); it++)str += (*it);293         FOLLOW.push_back(make_pair(*iter, str));294     }295 }296 297 298 //输出所有非终结符的FOLLOW集299 void Set::Show_Follow()300 {301     cout << "  " << "FOLLOW集" << " " << endl << endl;302     for (int i = 0; i < (int) FOLLOW.size(); i++){303         cout << FOLLOW[i].first << "";304         for (int j = 0; j <(int) FOLLOW[i].second.size(); j++){305             cout << FOLLOW[i].second[j] << " ";306         }307         cout << endl;308     }309     cout << endl;310 }311 312 313 //求解SELECT集314 void Set::Select_Solve()315 {316     multimap<char, string>::iterator iter;317     vector<PP >::iterator it;318     set<char >st;319     for (iter = Grammars.begin(); iter != Grammars.end(); iter++){320         char ch = iter->first;321         string str = iter->second;322         bool flag = true;323         st.clear();324         for (int i = 0; i < (int)str.size(); i++){325             if (Ok.find(str[i]) == Ok.end()&& str[i] != '~'){326                 flag = false;327             }328         }329         //求FIRST(a)330         int pos = 0;331         while (pos < (int)str.size() && Ok.find(str[pos]) != Ok.end()){332             for (it = FIRST.begin(); it != FIRST.end(); it++){333                 if (str[pos] == it->first)break;334             }335             for (int j = 0; j < (int)it->second.size(); j++){336                 st.insert(it->second[j]);337             }338             pos++;339         }340         if (pos < (int)str.size()){341             if (isupper(str[pos])){342                 for (it = FIRST.begin(); it != FIRST.end(); it++){343                     if (str[pos] == it->first)break;344                 }345                 for (int j = 0; j < (int)it->second.size(); j++){346                     st.insert(it->second[j]);347                 }348             }else 349                 st.insert(str[pos]);350         }351         //如果产生式A->a并且a能推出空,则SELECT(A->a)=(FIRST(a)-{~})U(FOLLOW(A)352         if (flag){353             for (it = FOLLOW.begin(); it != FOLLOW.end(); it++){354                 if (ch == it->first)break;355             }356             for (int j = 0; j < (int)it->second.size(); j++){357                 st.insert(it->second[j]);358             }359             for (set<char>::iterator ii = st.begin(); ii != st.end(); ){360                 if ((*ii) == '~'){361                     ii = st.erase(ii);362                     break;363                 }364                 ii++;365             }366             string ss = "";367             for (set<char>::iterator ii = st.begin(); ii != st.end(); ii++)ss += (*ii);368             SELECT.push_back(make_pair(ch, make_pair(str,ss)));369         }370         //否则SELECT(A->a)=(FIRST(a)371         else {372             string ss = "";373             for (set<char>::iterator ii = st.begin(); ii != st.end(); ii++)ss += (*ii);374             SELECT.push_back(make_pair(ch, make_pair(str,ss)));375         }376     }377 }378 379 380 //输出SELECT集381 void Set::Show_Select()382 {383     cout << "  " << "SELECT集" << " " << endl << endl;384     for (int i = 0; i < (int) SELECT.size(); i++){385         cout << SELECT[i].first << " ->";386         cout << setw(4) << SELECT[i].second.first << " :   ";387         for (int j = 0; j < (int) SELECT[i].second.second.size(); j++){388             cout << SELECT[i].second.second[j] << " ";389         }390         cout << endl;391     }392     cout << endl;393 }394 395 396 //预测分析程序397 void Set::Analysis()398 {399     cout << "请输入要识别的串: " << endl;400     string str;401     cin >> str;402     for (int i = 0; i < (int)str.size(); i++){403         Sentence.push_back(str[i]);404     }405     Sentence.push_back('#');406     vector<char>::iterator iter = Sentence.begin(), ii;407     stack<char>S;408     vector<char>vet;409     S.push('#');410     S.push('S');411     vet.push_back('#');412     vet.push_back('S');413     cout << "分析栈" << "              " << "剩余输入串" << "              " << "推倒所用的产生式或匹配" << endl;414     int EMPTY = 7;415     while (!S.empty()){416         for (int i = 0; i < (int)vet.size(); i++){417             cout << vet[i] << " ";418         }419         for (int i = (int)vet.size(); i <= EMPTY+2; i++)cout << "  ";420         int count = 0;421         for (ii = iter; ii != Sentence.end(); ii++){422             cout << (*ii) << " ";423             count++;424         }425         for (; count <= EMPTY; count++)cout << "  ";426         char ch = S.top();427         if (ch == (*iter)){428             S.pop();429             vet.pop_back();430             iter++;431             for (int i = 0; i <= EMPTY; i++)cout << "  ";432             cout << "匹配" << endl;433         }434         else {435             vector<PPP >::iterator it;436             string ss = "";437             bool flag = false;438             for (it = SELECT.begin(); it != SELECT.end(); it++){439                 if (it->first == ch){440                     ss = it->second.first;441                     for (int i = 0; i < (int)it->second.second.size(); i++){442                         if (it->second.second[i] == (*iter)){443                             flag = true;444                             break;445                         }446                     }447                     if (flag)break;448                 }449             }450             for (int i = 0; i <= EMPTY; i++)cout << "  ";451             if (!flag){452                 cout << "ERROR!!!" << endl;453                 return;454             }455             cout << ch << "->" << ss << endl;456             reverse(ss.begin(), ss.end()); //反转457             if (ss == "~"){458                 S.pop();459                 vet.pop_back();460             }461             else {462                 S.pop();463                 vet.pop_back();464                 for (int i = 0; i < (int)ss.size(); i++){465                     S.push(ss[i]);466                     vet.push_back(ss[i]);467                 }468             }469         }470     }471     cout << "SUCCESS" << endl;472 }473 474 475 476 int main()477 {478     Set obj;479     obj.Get_Ok(); 480     obj.First_Solve();481     obj.Show_First();482     obj.Follow_Solve();483     obj.Show_Follow();484     obj.Select_Solve();485     obj.Show_Select();486     obj.Analysis();487     return 0;488 }
View Code

 

0 0
原创粉丝点击