编译原理实习(应用预测分析法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 }
0 0
- 编译原理实习(应用预测分析法LL(1)实现语法分析)
- 编译原理实现预测分析法(LL(1))
- 自上而下的语法分析(递归下降法,LL(1)预测分析法,预测分析表)
- 编译原理(五) LL(1)文法分析法(预测分析表的构造算法C++实现)
- 编译原理(五) LL(1)文法分析法(预测分析表的构造算法C++实现)
- 预测分析法进行语法分析(编译原理)
- 编译原理学习笔记·语法分析(LL(1)分析法/算符优先分析法OPG)及例子详解
- 编译原理:LL(1)文法 语法分析器(预测分析表法)
- 编译原理:LL(1)文法 语法分析器(预测分析表法)
- 【编译原理】自上而下的语法分析之预测分析法
- 编译原理实验二——语法分析(预测分析)
- 编译原理-LL(1)预测分析实验 c源代码
- 编译原理(五) LL(1)文法分析法-预测分析表的构造
- 语法分析之LL(1)分析法
- 【C++】C++实现LL(1)语法分析
- 编译原理上机作业2——LL(1)语法分析
- LL(1)语法分析
- LL(1)语法分析
- loj 1002(spfa变形)
- hdu 4114(状压dp)
- loj 1379(最短路变形)
- loj 1271
- hdu 1063(java写高精度)
- 编译原理实习(应用预测分析法LL(1)实现语法分析)
- linux下java环境配置
- linux下vim配置以及一些常用的快捷键
- loj 1412(树上最长直径的应用)
- loj 1377 (bfs)
- loj 1426(dfs + bfs)
- 求阶乘的位数
- java大数取模
- [LeetCode]Next Permutation