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

  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
原文地址:https://www.cnblogs.com/wally/p/3427866.html