




已阅读5页,还剩47页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
合肥工业大学计算机与信息学院计算机系2013级编译原理课程设计报告姓 名: 马骏 专业年级: 信息安全13-1 学 号: 2013211869 提交时间: 2016年07月 1、 实验题目自上而下的LL(1)文法分析2、 实验目的了解掌握自上而下的LL(1)文法分析过程。二、实验内容与要求 从语法分析树构造句型所有的推导的程序实现,接受用户任意输入的一个句型的语法分析树(其表示存于指定文件中),生成该语法分析树中包含的该句型的所有推导(显示输出)。 构造一程序,实现教材P.78的FIRST(X)集合的构造算法。对任一给定的文法G,程序输出所有非终结符P的FIRST(P)。构造一程序,实现教材P.78的FIRST(X)集合的构造算法。对任一给定的文法G,程序输出所有非终结符P的FIRST(P)。在此基础上,构造一程序,实现教材P.79的FOLLOW(A)集合的构造算法。对任一给定的文法G,程序输出所有非终结符A的FOLLOW (A)。对于给定的一个LL(1)文法,假定所有非终结符号P的集合FIRST(P)和集合FOLLOW(P)都已知,构造其预测分析表(实现教材P.79给出的预测分析表构造算法)。对教材P.79给出的例4.7构造出预测分析表。程序显示输出预测分析表或输出到指定文件中。 首先实现集合FIRST(X)构造算法和集合FOLLOW(A)构造算法,再实现教材P.79给出的预测分析表构造算法。程序显示输出预测分析表或输出到指定文件中。 对文法按教材P.76表4.1构造出G的预测分析程序,程序显示输出如P.78那样的匹配过程。三、实验环境与工具操作系统:Windows 7开发语言:C+4、 开发过程1) 字符要求:你的程序必须能够根据以下字符来处理语法:- 终端字符:字母,数字,符号例如“+”,“ ”,;- 非终端字母表中的大写字母。符号“=”,“|”和“”(替换“”,因为它更容易输入到文本文件)被保留用于语法的描述中,因此不能被用作终端。2) 初始状态您的程序通过读取一个文件中的“文本”格式开始。这个文件的结构可以随意构建,不做要求,但建议做成简单的。例如,程序描述以下语句:E = E + T |TT = T * F |FF =(E)| 0 |1在这种情况,我们可以很容易确定E,T和F是非终端,而符号“(”,“)”,“*”和“+”和数字“0”和“1”是在终端。第一个非终端(第一衍生物)被认为是语法的公理。文本结构(在内存中)过程显示在屏幕结果必须存储在内存中,是一个您所选择的数据结构。然后,使用一个函数再取出数据,存储在内存中并屏幕上显示(以你选择的格式)。在上面的图中,并在下文中,右列显示的程序的执行的过程,并左栏表示中使用的数据结构。这些都是明显的例子。你可以使用任何你想要的格式。3)消除传递没有发现传递关系发现传递关系判断:是否包含左传递消除传递关系判断你的程序是否包含一个传递关系或没有。如果包含,递归应该被消除。没有传递关系的语句遍历语句指向自己的判断:您可以创建一个新的数据结构语句来表示其中传递关系已被删除,这有利于进一步加工。在这种情况下,如果语法不包含判定递归的语句,程序当然必须使用第二数据结构的副本。3)计算“first集”和“follow集”的集合为了产生一个分析器,你现在必须计算,每个分支,“第一个”和“其后”的集合。结果被存储在数据结构,再次“你的选择。”然后,这些集合被显示在屏幕上图注释:Calcul des ensembles premiers et suivants 计算“第一个”和“其后”的集合Affichage des ensembles 显示集合 premiers 第一个 suivants其后 4)分析表的结构具有非递归语法以及“第一个”和“其后”的集合,你的程序现在可以建立预测分析表。结果以表的形式显示在屏幕上。图注释:Construction de la table danalyse分析表的结构table danalyse 分析表 Affichage de la table danalyse 显示分析表输入字符串的分析最后一步:你的程序读取输入(键盘)的表达和分析。指出,结果是否符合语法。你要尽可能准确的鉴定结果:定位错误在没有辨认出表达式的情况下。其次,你的程序必须能够完成对输入多个字符串作为输入,不要忘记重新启动你的程序。显示分析结果判断是否继续读取表达式5、 程序实现6、 程序代码/*不支持规则源文件中有空格注意 使用#表示空产生式 使用$表示结束符# */#include#include#include#includeusing namespace std;const char* sourcefile=ma_grammaira.txt; /定义源文件/const int max=100;#define max 100class signpublic:sign()sign(int check,char fu)if(check!=0&check!=1) /符号属性只有0和1couterror sign creat!=funnumber|q0)couterror wrong delete fun in sign!;return;for(int x=q;xfunnumber-1;x+)funx=funx+1;funnumber-;void pop_first(char q)/从first集删除某一节点for(int x=0;xfirstnumber;x+)if(firstx=q)for(int y=x;yfirstnumber-1;y+)firsty=firsty+1;firstnumber-;x-;/为了接着上次检查点void pop_follow(char q)/从first集删除某一节点for(int x=0;xfollownumber;x+)if(followx=q)for(int y=x;yfollownumber-1;y+)followy=followy+1;follownumber-;x-;/为了接着上次检查点void add_first(char q)/向first添加元素for(int x=0;xfirstnumber;x+)if(firstx=q)return; firstfirstnumber=q;firstnumber+;void add_follow(char q)/向follow添加元素for(int x=0;xfollownumber;x+)if(followx=q)return; followfollownumber=q;follownumber+;int identity; /符号属性0为非终结符 1为终结符char id; /符号string funmax;/符号产生规则int funnumber; /符号产生规则数量char firstmax;/first集 int firstnumber; char followmax;/follow集 int follownumber;class cell /分析表的单元格结构public: char cell_unendsign;/终结符char cell_endsign;/非终结符string cell_fun;/产生式;cell tablemaxmax; /分析表数据结构int table_unend_number;/非终结符数int table_end_number;/终结符数sign unendsignmax;/非终结点集合int unendsignnumber=0;sign endsignmax;/终结点集合int endsignnumber=0;void readsource(const char*sf) /读取源文件ma_grammaira.txt int x;unendsignnumber=0;endsignnumber=0;ifstream ifs;ifs.open(sourcefile);char bufmax;for(x=0;xmax;x+)bufx=0;while(ifs.getline(buf,sizeof(buf) /一行一行读取unendsignunendsignnumber=sign(0,buf0);unendsignnumber+;string rule;for(int x=2;xmax;x+)if(bufx=0) break;if(bufx=|)/coutruleendl;unendsignunendsignnumber-1.fununendsignunendsignnumber-1.funnumber=rule;/规则放在每个非终结符实例中unendsignunendsignnumber-1.funnumber+;rule=;continue;rule+=bufx;char kk=bufx;unendsignunendsignnumber-1.fununendsignunendsignnumber-1.funnumber=rule;unendsignunendsignnumber-1.funnumber+;/coutruleendl;void addendsign(char sg) /添加终结符for(int x=0;xendsignnumber;x+)if(endsignx.id=sg)return;endsignendsignnumber.id=sg;endsignendsignnumber.identity=1;endsignnumber+;void dealend()/由非终结符产生式得到终结符for(int x=0;xunendsignnumber;x+)for(int y=0;yunendsignx.funnumber;y+)for(int z=0;z=65&int(kk)=90)continue; /A到Z为非终结符else addendsign(kk);bool exit_endsign(char sg) /终结符表是否有sgint x;for(x=0;xendsignnumber;x+)if(endsignx.id=sg) return true;return false;bool exit_unendsign(char sg) /非终结符表是否有sgfor(int x=0;xunendsignnumber;x+)if(unendsignx.id=sg)return true;return false;sign get_unendsign(char sg)/从非终结符表中得到非终结符为sg的实例for(int x=0;xunendsignnumber;x+)if(unendsignx.id=sg)return unendsignx;couterror get no unend sign!endl;sign er;return er;int get_unendsign_number(char sg)/从非终结符表中得到非终结符为sg的下标for(int x=0;xunendsignnumber;x+)if(unendsignx.id=sg)return x;couterror get no unend sign!endl;return 0;int get_endsign_number(char sg)/从非终结符表中得到终结符为sg的下标for(int x=0;xendsignnumber;x+)if(endsignx.id=sg)return x;couterror get no end sign!endl;return 0;bool rule_first_check(sign m_sign,char sg)/查看非终结符实例m_sign 产生式首是否为sg int y;for(y=0;ym_sign.funnumber;y+)if(m_sign.funy0=sg)return true;int check=0;for(y=0;ym_sign.funnumber;y+)if(exit_unendsign(m_sign.funy0)sign msg=get_unendsign(m_sign.funy0);if(rule_first_check(msg,sg)check=1;break;if(check)return true;else return false;bool check_L_recursion()/检查是否含有直接左递归和传递左递归 true表示有 false表示没有 int x,y;for(x=0;xunendsignnumber;x+) /检查直接左递归for(y=0;yunendsignx.funnumber;y+)if(unendsignx.funy0=unendsignx.id)return true;for(x=0;x90|unendsignnumber26)couterror no more size for unend sign!endl;break;int check=1; for(int x=0;xunendsignnumber;x+)if(unendsignx.id=a)a+;check=0;break;if(check)unendsignunendsignnumber.id=a;unendsignunendsignnumber.identity=0;unendsignnumber+;break;return unendsignunendsignnumber-1;void pop_unendsign(char sg) /删除某一非终结符for(int x=0;xunendsignnumber;x+)if(unendsignx.id=sg)for(int y=x;yunendsignnumber-1;y+)unendsigny=unendsigny+1;unendsignnumber-;return;couterror no unend sign for popendl;return;void deal_direct_L_recursion(int thisnumber) /消除 unendsignthisnumber的直接左递归 在deal_L_total_recursion()中调用 int i;if(!check_L_recursion()return;int check=0;for(i=0;iunendsignthisnumber.funnumber;i+) /先检查 unendsignthisnumber是否存在 直接左递归 if(unendsignthisnumber.funi0=unendsignthisnumber.id)check=1;break;if(check)new_unendsign();int kp=unendsignnumber-1;for(i=0;ib0p|b1pif(unendsignthisnumber.funi0=unendsignthisnumber.id)string ss=;for(int x=1;xunendsignthisnumber.funi.length();x+)ss+=unendsignthisnumber.funix;if(ss=#)coutP# # 的规则for(i=0;ip. 的产生式if(unendsignthisnumber.funi0=unendsignthisnumber.id)unendsignthisnumber.pop(i);i=0;void deal_L_total_recursion()/消除所有左递归 int i,j,t,k,qq;for(i=0;iunendsignnumber;i+)for(j=0;ji;j+)for( t=0;tunendsigni.funnumber;t+)if(unendsigni.funt0=unendsignj.id)string say=;for( k=1;kunendsigni.funt.length();k+)say+=unendsigni.funtk;unendsigni.pop(t);for( qq=0;qqunendsignj.funnumber;qq+)string sp=unendsignj.funqq;if(sp!=#)sp+=say;unendsigni.add(sp);deal_direct_L_recursion(i); /消除Pi 的直接左递归void deal_first_club()/求各节点的first集 int x,t;for(x=0;xendsignnumber;x+)endsignx.add_first(endsignx.id);int check=1;while(check)check=0;for(x=0;xunendsignnumber;x+)int oldnumber=unendsignx.firstnumber; /用于记录first集是否再增大for(t=0;tunendsignx.funnumber;t+) unendsignx.add_first(unendsignx.funt0);for(t=0;tunendsignx.firstnumber;t+)if(exit_unendsign(unendsignx.firstt)int kp=get_unendsign_number(unendsignx.firstt);for(int q=0;qunendsignkp.firstnumber;q+)if(unendsignkp.firstq!=#)unendsignx.add_first(unendsignkp.firstq);if(unendsignx.firstnumber!=oldnumber)check=1;check=1;while(check)check=0;for(x=0;xunendsignnumber;x+) /判断first是否应包含# for(int y=0;yunendsignx.funnumber;y+) int overcheck=1; for(int t=0;tABCD. int thischeck=1;for(int t=0;tunendsignx.funy.length();t+)int oop=get_unendsign_number(unendsignx.funyt);int incheck=0;for(int z=0;zunendsignoop.firstnumber;z+)if(unendsignoop.firstz=#)incheck=1;break;if(incheck) continue;else thischeck=0;break;if(thischeck)int sp=unendsignx.firstnumber;unendsignx.add_first(#);if(sp!=unendsignx.firstnumber) check=1; for(x=0;xunendsignnumber;x+)/消除first集中的非终结符for(int y=0;yunendsignx.firstnumber;y+)if(exit_unendsign(unendsignx.firsty)unendsignx.pop_first(unendsignx.firsty); y-;void deal_follow_club() /求每个非终结符的follow集 int x,y,z,t;unendsign0.add_follow($);/在开始符号的follow集中添加结束符$ int check=1; while(check) /循环至follow集不在增大check=0;for(x=0;xunendsignnumber;x+)for( y=0;yunendsignx.funnumber;y+)for( z=0;zunendsignx.funy.length();z+)if(exit_unendsign(unendsignx.funyz)&z.A kp=get_unendsign_number(unendsignx.funyz);int ss=unendsignkp.follownumber;if(unendsignx.funyz+1!=#)unendsignkp.add_follow(unendsignx.funyz+1);if(unendsignkp.follownumber!=ss)check=1; if(z=unendsignx.funy.length()-1&exit_unendsign(unendsignx.funyz) /p-.Bint kp=get_unendsign_number(unendsignx.funyz);for(t=0;tunendsignx.follownumber;t+)int ssp=unendsignkp.follownumber;unendsignkp.add_follow(unendsignx.followt);if(unendsignkp.follownumber!=ssp)check=1;if(exit_unendsign(unendsignx.funyz)&z.SABC 其中#在ABC的first集中for(int i=z+1;iunendsignx.funy.length();i+)if(exit_unendsign(unendsignx.funyi)int thisthischeck=0;int kp=get_unendsign_number(unendsignx.funyi);for(int pp=0;ppunendsignkp.firstnumber;pp+)if(unendsignkp.firstpp=#)thisthischeck=1;break;if(thisthischeck)continue;elsethischeck=0;break;thischeck=0;break;if(thischeck)int kp=get_unendsign_number(unendsignx.funyz); for(t=0;tunendsignx.follownumber;t+)int ssp=unendsignkp.follownumber;unendsignkp.add_follow(unendsignx.followt);if(unendsignkp.follownumber!=ssp)check=1; for(x=0;xunendsignnumber;x+) /非终结点在follow集则要把 其first集除#放入follow集for(y=0;yunendsignx.follownumber;y+)if(exit_unendsign(unendsignx.followy)int kp=get_unendsign_number(unendsignx.followy);for(t=0;tunendsignkp.firstnumber;t+)if(unendsignkp.firstt=#)continue;elseint oop=unendsignx.follownumber;unendsignx.add_follow(unendsignkp.firstt);if(unendsignx.follownumber!=oop)check=1;for(x=0;xunendsignnumber;x+) /删除follow集中的非终结点for(int y=0;yunendsignx.follownumber;y+)if(exit_unendsign(unendsignx.followy)unendsignx.pop_follow(unendsignx.followy);y-; void init_LL_table() /分析表初始化 int x,y;addendsign($);table_unend_number=0;table_end_number=0;for(x=0;xunendsignnumber;x+)for(y=0;yendsignnumber;y+)tablexy.cell_endsign=endsigny.id;tablexy.cell_unendsign=unendsignx.id;coutinit table begin:endl;for(x=0;xunendsignnumber;x+)for(y=0;yendsignnumber;y+)couttablexy.cell_unendsign:tablexy.cell_endsign ;coutendl;void deal_LL_table()/ 产生LL(1)文法分析表 int x,j,y,t;init_LL_table(); for(x=0;xunendsignnumber;x+)for(y=0;yA #一直属于Aif(i=unendsignx.funy.length()break;check=0;if(exit_unendsign(unendsignx.funyi) /P-A 将A的first集的终结符 单元格 赋值P-Aint kp=get_unendsign_number(unendsignx.funyi);for(t=0;ta a是非终结符if(unendsignx.funyi!=#)j=get_endsign_number(unendsignx.funyi);tablexj.cell_fun=unendsignx.funy;if(unendsignx.funyi=#&i=0)check=1;break;if(check) /P-A如果#属于Afor(t=0;tunendsignx.follownumber;t+)if(unendsignx.followt!=#) j=get_endsign_number(unendsignx.followt); tablexj.cell_fun=unendsignx.funy;for(x=0;xunendsignnumber;x+) /没有产生式的单元格标记为错误for(y=0;y0)continue;else tablexy.cell_fun=error;void analizeLL_1() /预测分析程序string putin;char stackmax;int stacknumber=0;stackstacknumber=$;stack
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年湖北省百强县中考数学联考试卷(4月份)
- 客户洞察面试题及答案
- 广告设计师考试综合设计能力试题及答案
- 端口测试面试题及答案
- 2024年纺织设计师考试的道德与试题及答案
- 保险从业考试题库及答案
- 2024助理广告师考试备考真经试题及答案
- 2024年助理广告师考试的挑战与机遇试题及答案
- 2024年设计师客户需求分析题及答案
- 助理广告师考试情感与品牌联结试题及答案
- 市政道路交通导改方案
- (广东二模)2025年广东省高三高考模拟测试(二)语文试卷(含答案解析)
- SL631水利水电工程单元工程施工质量验收标准第3部分:地基处理与基础工程
- 新22J01 工程做法图集
- 水磨钻挖孔施工方案.
- 96拖拉机拨叉的数控编程加工设计
- UPS电子商务物流案例分析ppt课件
- 数学趣味小故事(课堂PPT)
- 井架现场施工方法
- 2017普通高中地理课程标准
- 污水处理规章制度及操作规程
评论
0/150
提交评论