编译原理实习(应用预测分析法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 }