![复制代码]()
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 }
![复制代码]()