直接上代码:

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<map>
  4 #include<vector>
  5 #include<string>
  6 #include<set>
  7 #include<stack>
  8 #include<algorithm>
  9 #include<Windows.h>
 10 using namespace std;
 11
 12 vector<char>VN;
 13 vector<char>VT;
 14 bool vis_VN[30];
 15 bool vis_VT[300];
 16 bool LL_flag=true;
 17 void init_visit()
 18 {
 19     for(int i=0;i<26;i++)
 20         vis_VN[i]=true;
 21     for(int i=0;i<300;i++)
 22         vis_VT[i]=true;
 23 }
 24
 25 map<char,vector<string> >mp;//用来存文法
 26 map<char,set<char> >first;//用来存first集
 27 map<char,set<char> >follow;//用来存follow集
 28 map<char,map<char,set<string> > >pretable;//预测分析表
 29
 30 bool is_VN(char x)//判断是否是非终结符
 31 {
 32     if(x>='A'&&x<='Z')
 33         return true;
 34     else
 35         return false;
 36 }
 37
 38 void fun_table(char A,string str)//预测分析表的构建
 39 {
 40     set<char>ans;
 41     bool tbool=false;
 42     for(int i=0;i<str.size();i++)
 43     {
 44         char ch=str[i];
 45         if( !( is_VN(ch) ) )//以终结符开头
 46         {
 47             if(ch !='0')
 48             {
 49                 ans.insert(ch);
 50                 tbool=true;
 51             }
 52                break;
 53         }
 54         else
 55         {
 56                set<char>::iterator it;
 57                for (it = first[ch].begin(); it != first[ch].end(); it++){
 58                    if(*it!='0')
 59                        ans.insert(*it);
 60                }
 61                tbool=true;
 62                for(int j=0;j<mp[ch].size();j++)
 63                {
 64                    if(mp[ch][j]=="0")
 65                        tbool=false;
 66                }
 67                if(tbool) break;
 68         }
 69     }
 70     if(!tbool)
 71     {
 72         set<char>::iterator it;
 73         for (it = follow[A].begin(); it != follow[A].end(); it++){
 74                if(*it!='0')
 75                    ans.insert(*it);
 76         }
 77     }
 78     set<char>::iterator it;
 79     for (it = ans.begin(); it != ans.end(); it++){
 80         pretable[A][*it].insert(str);
 81     }
 82 }
 83
 84 void fun_first(char A)//处理A的first集
 85 {
 86     string flag="";
 87     bool empty_flag=true;
 88     for(int i=0;i<mp[A].size();i++)
 89     {
 90         flag=mp[A][i];
 91         for(int flagi=0;flagi<flag.size();flagi++)
 92         {
 93             char ch=flag[flagi];
 94             if( !( is_VN(ch) ) )//以终结符开头
 95             {
 96                 first[A].insert(ch);
 97                 empty_flag=false;
 98                 break;
 99             }
100             else
101             {
102                 fun_first(ch);
103                 set<char>::iterator it;
104                 for (it = first[ch].begin(); it != first[ch].end(); it++){
105                     if(*it!='0')
106                         first[A].insert(*it);
107                 }
108                 bool tbool=true;
109                 for(int j=0;j<mp[ch].size();j++)
110                 {
111                     if(mp[ch][j]=="0")
112                         tbool=false;
113                 }
114                 if(tbool)
115                 {
116                     empty_flag=false;
117                     break;
118                  }
119             }
120         }
121         if(empty_flag)
122             first[A].insert('0');
123     }
124 }
125
126 void fun_follow(char A)//处理A的follow集
127 {
128     for(int i=0;i<VN.size();i++)
129     {
130         char ch=VN[i];
131         for(int j=0;j<mp[ch].size();j++)
132         {
133             string s=mp[ch][j];
134             int k=0;
135             for(k=0;k<s.length();k++)
136             {
137                 if(s[k]==A)
138                 {
139                     if(k==s.length()-1)//如果A可直接或间接位于ch推导式的末位 ,将ch的follow集加入到A的follow集
140                     {
141                         set<char>::iterator it;
142                         for (it = follow[ch].begin(); it != follow[ch].end(); it++)
143                         {
144                             follow[A].insert(*it);
145                         }
146                     }
147                     else
148                     {
149                         if(is_VN(s[k+1]))//A的下一位是非终结符
150                         {
151                             bool flag2=false;
152                             set<char>::iterator it;
153                             for (it = first[s[k+1]].begin(); it != first[s[k+1]].end(); it++){
154                                 if(*it!='0')
155                                     follow[A].insert(*it);//将A下一位非终结符的first加入A的follow集 (除去0)
156                             }
157                             for(int t=0;t<mp[s[k+1]].size();t++)
158                             {
159                                 if(mp[s[k+1]][t]=="0")
160                                     flag2=true;
161                             }
162                             if(flag2)//A下一位非终结符可推倒出0
163                                 s[k+1]=A;
164                         }
165                         else
166                         {
167                             follow[A].insert(s[k+1]);
168                         }
169                     }
170                 }
171             }
172         }
173     }
174 }
175
176 void show_first_follow()//显示first集和follow集
177 {
178     cout<<"First集如下:"<<endl;
179     for(int i=0;i<VN.size();i++)
180     {
181         fun_first(VN[i]);
182         cout<<VN[i]<<": ";
183         char tch=VN[i];
184         set<char>::iterator it;
185         for (it = first[tch].begin(); it != first[tch].end(); it++){
186                 cout<<*it<<" ";
187         }
188         cout<<endl;
189     }
190     cout<<"Follow集如下:"<<endl;
191     follow[VN[0]].insert('#');
192     for(int i=0;i<VN.size();i++)
193         fun_follow(VN[i]);
194     for(int i=0;i<VN.size();i++)
195     {
196         fun_follow(VN[i]);
197
198         cout<<VN[i]<<": ";
199         char tch=VN[i];
200         set<char>::iterator it;
201         for (it = follow[tch].begin(); it != follow[tch].end(); it++){
202                 cout<<*it<<" ";
203         }
204         cout<<endl;
205     }
206 }
207
208 void show_pretable()//显示预测分析表
209 {
210     cout<<"预测分析表如下:"<<endl;
211     int x=VN.size()+1,y=VT.size()+1;
212     int spaceflag=0;
213     for(int i=1;i<=2*x+1;i++)
214     {
215         for(int j=1;j<=12*y+1;j++)
216         {
217             if(i%2==1)
218                 cout<<'-';
219             else
220             {
221                 if(i==2&&j%12==7&&j>12)
222                     cout<<VT[j/12-1];
223                 else
224                 {
225                     if(j%12==1)
226                         cout<<'|';
227                     else if(j==7&&i>2)
228                         cout<<VN[i/2-2];
229                     else
230                     {
231                         if(i>3&&j>13)
232                         {
233                             if(j%12==3)
234                             {
235                                 int m=i/2-2,n=j/12-1;
236                                 set<string>::iterator it;
237                                 if(!pretable[VN[m]][VT[n]].empty())
238                                 {
239                                     spaceflag-=pretable[VN[m]][VT[n]].size()-1;
240                                     if(pretable[VN[m]][VT[n]].size()>1)
241                                         LL_flag=false;
242                                 }
243                                 for (it = pretable[VN[m]][VT[n]].begin(); it != pretable[VN[m]][VT[n]].end(); it++){
244                                            cout<<*it<<" ";
245                                            spaceflag-=(*it).size();
246                                    }
247                                    if(spaceflag==0)
248                                     cout<<' ';
249
250                             }
251                             else
252                             {
253                                 if(spaceflag==0)
254                                     cout<<' ';
255                                 else
256                                     spaceflag++;
257                             }
258                         }
259                         else
260                             cout<<' ';
261
262                     }
263                 }
264
265             }
266         }
267         cout<<endl;
268     }
269
270 }
271
272 string stackstr,teststr;
273 void controlling()//总控程序+过程显示+错误处理
274 {
275     cout<<"Please input a string:"<<endl;
276     string checkstr;
277     stack<char>checkstack;
278     checkstack.push('#');
279     checkstack.push(VN[0]);
280     stackstr="#";
281     stackstr+=VN[0];
282     getchar();
283     cin>>checkstr;
284     checkstr+='#';
285     teststr=checkstr;
286     bool strflag=true;
287     int where;
288     for(int i=0;i<checkstr.size();i++)
289     {
290         if(checkstack.top()!='0')
291         {
292             cout<<stackstr;
293                 for(int j=1;j<=20-stackstr.length();j++)
294                     cout<<" ";
295             cout<<checkstr[i]<<"          ";
296             for(int j=i+1;j<checkstr.size();j++)
297                 cout<<checkstr[j];
298             cout<<endl;
299         }
300
301
302         if(checkstack.empty())
303         {
304             strflag=false;
305             where=i;
306             break;
307         }
308         char ch1=checkstack.top(),ch2=checkstr[i];
309         checkstack.pop();
310         if(ch1=='0')
311         {
312             i--;
313             continue;
314         }
315         if(!is_VN(ch1))
316         {
317             if(ch1!=ch2)
318             {
319                 strflag=false;
320                 where=i;
321                 break;
322             }
323             stackstr.erase(stackstr.end()-1,stackstr.end()) ;
324         }
325         else
326         {
327             if(pretable[ch1][ch2].empty())
328             {
329                 strflag=false;
330                 where=i;
331                 break;
332             }
333             else
334             {
335                 stackstr.erase(stackstr.end()-1,stackstr.end()) ;
336                 set<string>::iterator it;
337                 it=pretable[ch1][ch2].begin();
338                 string s=*it;
339                 for(int j=s.length()-1;j>=0;j--)
340                 {
341                     checkstack.push(s[j]);
342                     if(s[j]!='0')
343                         stackstr+=s[j];
344                 }
345                 i--;
346             }
347         }
348     }
349     if(strflag)
350         cout<<"ok";
351     else
352     {
353         cout<<"error near column "<<where+1<<endl;
354         for(int i=0;i<checkstr.length()-1;i++)
355         {
356             if(i==where)
357             {
358                 HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
359                 WORD wOldColorAttrs;
360                 CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
361
362                 // Save the current color
363                 GetConsoleScreenBufferInfo(h, &csbiInfo);
364                 wOldColorAttrs = csbiInfo.wAttributes;
365
366                 // Set the new color
367                 SetConsoleTextAttribute(h, FOREGROUND_RED | FOREGROUND_INTENSITY | BACKGROUND_GREEN);
368                 cout<<checkstr[i];
369                 SetConsoleTextAttribute(h, wOldColorAttrs);
370                 continue;
371
372             }
373             cout<<checkstr[i];
374         }
375         if(where==checkstr.length()-1)
376         {
377             HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
378             WORD wOldColorAttrs;
379             CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
380
381             // Save the current color
382             GetConsoleScreenBufferInfo(h, &csbiInfo);
383             wOldColorAttrs = csbiInfo.wAttributes;
384
385             // Set the new color
386             SetConsoleTextAttribute(h, FOREGROUND_RED | FOREGROUND_INTENSITY | BACKGROUND_GREEN);
387             cout<<'?';
388             SetConsoleTextAttribute(h, wOldColorAttrs);
389         }
390     }
391 }
392
393 int main()
394 {
395     init_visit();
396     int k=1;
397     char vn;
398     string str;
399     while(cin>>vn&&vn!='#'&&cin>>str)
400     {
401         if(vis_VN[vn-'A']==true)//不重复存vn
402         {
403             VN.push_back(vn);
404             vis_VN[vn-'A']=false;
405         }
406         mp[vn].push_back(str);//代表vn可以推导出str
407         for(int i=0;i<str.size();i++)
408         {
409             if(!is_VN(str[i])&&vis_VT[(int)str[i]]==true&&str[i]!='0')
410             {
411                 VT.push_back(str[i]);
412                 vis_VT[(int)str[i]]=false;
413             }
414         }
415
416     }
417     VT.push_back('#');
418     sort(VT.begin(),VT.end()-1);
419     show_first_follow();
420     for(int i=0;i<VN.size();i++)//构建预测分析表
421     {
422         for(int j=0;j<mp[VN[i]].size();j++)
423         {
424             fun_table(VN[i],mp[VN[i]][j]);
425         }
426     }
427     show_pretable();
428     if(LL_flag)
429         cout<<"This is a LL(1)"<<endl;
430     else
431     {
432         cout<<"This is not a LL(1)"<<endl;
433         return 0;
434     }
435     while(1)
436     {
437         controlling();
438         cout<<endl;
439     }
440
441
442 }

样例:

E TA
A +E
A 0
T FB
B T
B 0
F PC
C *C
C 0
P (E)
P a
P b
P v
#S Ab
A a
A b
A 0
#S ABc
A a
A 0
B b
B 0
#

转载于:https://www.cnblogs.com/eastblue/p/8877431.html

编译原理预测分析程序相关推荐

  1. 编译原理预测分析法c语言,编译原理预测分析法C语言的实验报告.doc

    题目:编写识别由下列文法所定义的表达式的预测分析程序. EàE+T | E-T | T TàT*F | T/F |F Fà(E) | i 输入:每行含一个表达式的文本文件. 输出:分析成功或不成功信息 ...

  2. LL(1)预测分析程序

    分析程序源代码: LL1分析程序(包含c源码) 文法: E -> E+F | E-F | T T -> T*F | T/F | F F -> i | (E) 注:这实际上就是包含括号 ...

  3. 语法分析器---预测分析程序

    实验二  预测分析算法的设计与实现 (8学时) 一.实验目的 通过预测分析算法的设计与实现,加深对自上而下语法分析方法的理解,尤其是对自上而下分析条件的理解. 二.实验要求   输入文法及待分析的输入 ...

  4. LL(1)预测分析程序C++实现

    已知文法G如下,通过已知的预测分析表,输入要分析的字符串,得到分析结构附后. 已知文法G: E->TE' E'->+TE' E'->e T->FT' T'->*FT' T ...

  5. 【编译原理】分析PL0编译器

    转载自 分析PL0词法分析程序 原博的排版有些不易读.补充了部分内容

  6. 编译原理 自顶向下分析

    从顶部的根节点到底部的叶节点分析方法叫做自顶向下分析.我们知道顶部的根节点可以表示成一个文法的开始符号S,所以说,自顶向下分析可以看成是从文法的开始符号S推导出词串w的过程. 例如,我们以输入id + ...

  7. 编译原理 LR分析(主要是LR(0)分析)

    一.LR分析的基本原理 1.LR分析的基本思想 LR方法的基本思想就是,在规范归约的过程中,一方面要记住已移进和归约出的整个字符串,也就是说要记住历史:一方面能够根据所用的产生式的推测未来可能碰到的输 ...

  8. 编译原理-LR分析技术(自己看)

    放一个玄学解释图,其实我也看不大懂 只需要记住 栈顶这个关键词就好 案例 得到LR表(d代表数字) 求取表达式2+3*5 栈如下,从上到下:(第一个输入5,所以动作应该为s5)

  9. 编译原理:LL(1)文法 语法分析器(预测分析表法)

    设计要求:对于任意输入的一个LL(1)文法,构造其预测分析表,并对指定输入串分析其是否为该文法的句子. 思路:首先实现集合FIRST(X)构造算法和集合FOLLOW(A)构造算法,再根据FIRST和F ...

最新文章

  1. 牛津大学名誉教授Colin Blakemore:大脑是如何计算的?
  2. 使用post向webservice发送请求,并且返回值
  3. 《高效程序员的修炼》 读书笔记
  4. 理解GBDT算法(三)——基于梯度的版本
  5. Deeplearnng.AI第四部分第一周、卷积神经网络
  6. Python 的文件IO相关操作说明
  7. gmail收件箱标签设置_通过在Gmail中启用实验室功能来启动收件箱
  8. 信息学奥赛C++语言:判断正负
  9. 使用PostgREST的RestAPI操作之 类型转JSON对象 | 嵌入视图
  10. IIS6、IIS7和IIS8各版本的差别
  11. 图片转字符画-----做出酷炫的头像
  12. 解决页面怎么模拟手机端屏幕
  13. JSR303校验的简单使用以及自定义校验规则的代码编写
  14. 上海联通第一家冰激凌无限店正式开业,拥抱新零售时代!
  15. JavaScript比较运算大于小于等于
  16. Dremel学习总结2
  17. 社区说 | Flutter 工程那些事儿
  18. 解决VMware中centos 7虚拟机,主ip地址:网络信息不可用。
  19. 西雅图华人码农生存实录
  20. 谈谈网银和USB Key

热门文章

  1. [iOS]Unable to run app in Simulator
  2. 在Ubuntu下设置笔记本外接显示器(双显示器)
  3. python自动登录百度空间
  4. make -j32 21 | tee show.log
  5. [react] react的性能优化在哪个生命周期?它优化的原理是什么?
  6. react学习(56)--常见HTTP错误
  7. [vue] 说说你对SPA单页面的理解,它的优缺点分别是什么?
  8. 工作262:HBuilderX常见快捷键
  9. 工作总结14:路径错误
  10. 工作总结10:解决vuex刷新数据消失