编译原理专业课程设计LL文法分析器设计C语言实现_第1页
编译原理专业课程设计LL文法分析器设计C语言实现_第2页
编译原理专业课程设计LL文法分析器设计C语言实现_第3页
编译原理专业课程设计LL文法分析器设计C语言实现_第4页
编译原理专业课程设计LL文法分析器设计C语言实现_第5页
已阅读5页,还剩36页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

集美大学计算机工程学院编译原理课程设计汇报选题名称:LL(1)文法分析 院(系): 计 算 机 工 程 学院 专业: 计算机科学和技术 班级:计算1412 指导老师:付永刚年学期: ~ 年第2学期 年 06 月29 日摘要:选题要求:依据某一文法编制调试LL(1)文法语法分分析程序,方便对任意输入符号串进行分析。此次课程设计目标关键是加深对估计分析LL(1)文法语法分析法了解。具体以下:1、对语法规则有明确定义;2、编写分析程序能够对给定文法进行正确语法分析;3、对输入给定文法,手工计算FIRST、FOLLOW集合和select集合,应能判定识别是否为给定文法句子,并给出推导过程。4、对输入给定文法,由程序自动结构FIRST、FOLLOW集合。5、对于碰到语法错误,能够做出简单错误处理,给出简单错误提醒,确保顺利完成语法分析过程。

关键词:语法分析;FIRST集合;FOLLOW集合;分析表一、设计内容及要求(1)基于PL/0语言,经过编程判定该文法是否为LL(1)文法;(2)计算出文法First()Follow()(3)结构对应文法估计分析表(4)对某个输入句子进行语法分析二、实现原理1.LL(1)文法LL(1)文法是一类能够进行确定自顶向下语法分析文法。就是要求描述语言文法是无左递归和无回溯。依据LL(1)文法定义,对于同一非终止符A任意两个产生式A:=a和A:=b,全部要满足:SELECT(A:=a)∩SELECT(A:=b)=Ø。(1)文法左递归当一个文法是左递归文法时,采取自顶向下分析法会使分析过程进入无穷循环之中。所以采取自顶向下语法分析需要消除文法左递归性。文法左递归是指若文法中对任一非终止符A有推导AÞA…,则称该文法是左递归。左递归又能够分为直接左递归和间接左递归。●直接左递归若文法中某一产生式形如A→Aα,α∈V*,则称该文法是直接左递归。消除直接左递归方法:设有产生式是相关非终止符A直接左递归:A→Aα|β(α,β∈V*,且β不以A开头)对A引入一个新非终止符A′,把上式改写为:A→βA′A′→αA′|ε●间接左递归若文法中存在某一非终止符A,使得AÞA…最少需要两步推导,则称该文法是间接左递归。消除间接左递归方法:【方法一】采取代入法把间接左递归变成直接左递归。【方法二】直接改写文法:设有文法G10[S]:S→Aα|β⑴A→Sγ⑵因为SÞAαÞSγα,所以S是一个间接递归非终止符。为了消除这种间接左递归,将⑵式代入⑴式,即可得到和原文法等价文法(能够证实):S→Sγα|β⑶⑶式是直接左递归,能够采取前面介绍消除直接左递归方法,对文法进行改写后可得文法:S→βS′S′→γαS′|ε2.计算First集(1)若X∈VT,则First(X)={X}(2)若X∈VN,且有产生式X→a…,a∈VT则First(X)={X}(3)若X∈VN,且有产生式X→ε,则First(X)={X}(4)若X,Y1,Y2,…,Yn全部∈VN,而由产生式X→Y1Y2…Yn。当Y1,Y2,…,Yi-1全部能推导出ε时,(其中1≤i≤n),则First(Y1)-{ε},First(Y2)-{ε},…,First(Yi)全部包含在First(X)中(5)当(4)中全部Yi全部能推导出ε,(i=1,2,…,n),则First(X)=First(Y1)∪First(Y2)∪…First(Yn)∪{ε}反复使用上述步骤直到每个符合First集合不再增大为止。3.计算Follow集对文法中每个A∈VN,计算Follw(A):(1)设S为文法开始符合,把{#}加入Follow(S)中;(2)若A→αBβ是一个产生式,则把First(β)非空元素加入Follow(B)中,假如β能推导出ε,则把Follow(A)也加入(B)中;(3)反复使用以上步骤直到每个非终止符号Follow集不再增大为止。4.估计分析方法估计分析方法是自顶向下分析另一个方法,一个估计分析器是由三个部分组成:估计分析程序;优异后出栈;估计分析表。估计分析程序框图以下:目录1系统分析11.1选题要求11.2预期目标12.程序流程图12.1总流程图12.2First集和Follow集22.3预测分析表流程33.代码编写33.1检查左递归33.2first集合53.3follow集合63.4分析表输出84.程序调试105.总结116.指导教师评语127.源码13

正文:1.系统分析1.1选题要求依据某一文法编制调试LL(1)文法语法分分析程序,方便对任意输入符号串进行分析。此次课程设计目标关键是加深对估计分析LL(1)文法语法分析法了解。1.2预期目标结构LL(1)文法语法分析程序,任意输入一个文法符号串,并判定它是否为文法一个句子。程序要求为该文法结构估计分析表,并根据估计分析算法对输入串进行语法分析,判别程序是否符合已知语法规则,假如不符合(编译犯错),则输犯错误信息。程序步骤图2.1.总步骤图2.2.First集和Follow集步骤图2.3.估计分析表步骤:代码编写3.1检验左递归:Parser&Parser::DelLeft(inti){intn=StrNum(content[i]);charc=RandChar();charz=content[i][0];ints=0;for(intk=1;k<=n;k++){stringtmp=GetSub(k,content[i],'|');if(z==tmp[0])s=1;}if(s==0)return*this;cout<<"文法句"<<content[i]<<"含有直接左递归,";while(1){if(Findchar(c,non)==-1)break;elsec=RandChar();}cout<<"随机产生非终止符为:"<<c<<endl;non.append(1,c);stringtemp;temp+=z;temp+="->";stringnext;next+=c;next+="->";for(intk=1;k<=n;k++){stringt=GetSub(k,content[i],'|');if(z==t[0]){t.erase(0,1);t+=c;next+=t;next+='|';}else{if(t=="^")t.clear();t+=c;temp+=t;temp+='|';}}next+='^';temp.erase(temp.size()-1,1);content[i]=temp;num=num+1;content[num]=end;for(intj=num-1;j>i;j--)content[j]=content[j-1];content[i+1]=next;return*this;}3.2first集合stringParser::First(charx){stringch="";if(Findchar(x,ter)!=-1){ch.append(1,x);ch.append(1,'');}elseif(Findchar(x,non)!=-1){inti=Findid(x);if(i!=-1){stringq=content[i];unsignedintk=3;while(k<q.size()){if(q[k-1]=='|'||k==3){if(Findchar(q[k],ter)!=-1||q[k]=='^'){ch.append(1,q[k]);ch.append(1,'');}else{if(k==3||q[k+1]=='|'||k==q.size()-1)ch+=First(q[k]);else{stringtemp=First(q[k-1]);if(Findchar('^',temp)!=-1)ch+=First(q[k]);}}k++;}elsek++;}}}returnch;}3.3follow集合stringParser::Follow(charx){ stringch;if(Findchar(x,non)!=-1){if(!Findid(x)){ch+="$";ch+='';}inti=0;while(i<num){stringq=content[i];unsignedintk=3;charc=content[i][0];while(k<q.size()){while(q[k]==x){if(k<q.size()-1&&q[k+1]!='|'){stringtemp=Delchar('^',First(q[k+1]));if(ch.find(temp)==string::npos)ch+=temp;if(Findchar('^',First(q[k+1]))!=-1){stringfollow_c=Follow(c);if(ch!=follow_c&&ch.find(follow_c)==std::string::npos)ch+=follow_c;}}elseif(k==q.size()-1){stringfollow_c=Follow(c);if(ch.find(follow_c)==std::string::npos)ch+=follow_c;}k++;}k++;}i++;}}returnch;}3.4分析表输出intParser::Analysis(){stack.append("$"); charchose; cout<<"是否输入分析串(yorn):"; cin>>chose; while(chose=='y') { stack+=non[0]; cout<<"请输入分析串<退出(q)>:"; cin>>instack; if(instack=="q")exit(0); if(instack[instack.size()-1]!='$')instack+="$"; intk=1,flag=0; charx=Top(); charc=Ip(); cout<<"分析栈\t目前输入\t动作"<<endl; while(x!='$') { x=Top(); c=Ip(); cout<<stack<<"\t"<<instack<<"\t\t"; if(Findchar(x,ter)!=-1) { if(Mate(x,c)) { k++; cout<<"匹配"<<c<<endl; } else { cout<<"["<<k<<"]犯错(终止符不匹配)!"<<endl; flag=1; if(x==')')Pop(); elseinstack.erase(0,1);k++; } } elseif(Findchar(x,non)!=-1) { intidf=Findchar(x,non); intidz=Findchar(c,ter); if(idz==-1)idz=int(ter.size()); stringtemp=table[idf][idz]; if(temp.empty()) { cout<<"["<<k<<"]犯错("<<c<<"不属于FIRST("<<x<<"))!"<<endl; flag=1; instack.erase(0,1);k++; } else { Pop(); if(temp!="^") { Push(temp); cout<<x<<"->"<<temp<<endl; } elsecout<<x<<"->"<<temp<<endl; } } elseif(x=='$'&&c=='$') { if(flag==0)cout<<"正确"<<endl; elsecout<<"错误"<<endl; } else { cout<<"["<<k<<"]犯错(未能识别字符)!"<<endl; flag=1; instack.erase(0,1);k++; } } }}4.程序调试导入正确文法:符合文法串不符合文法串导入有左递归文法:串分析:总结经过这次课程设计,对于LL1文法认识有了深入提升,尤其是对于FIRST集合和FOLLOW集合求取,前面对于求取者两个集合了解还不是很好,经过这次课程设计,逐步了解了求解过程,而且知道了怎样经过代码,自动生成某LL1文法FIRST集合和FOLLOW集合,在刚开始做时,根本不知道求,经过网上查找资料,同学请教,慢慢地知道了怎样做,最终正确地求出FIRST集合和FOLLOW集合。而且能够使用者两个集合构建估计分析表和对一段输入串进行分析是否是该文法串,犯错地方能够做犯错处理,总来说,完成了课程设计要求大部分内容,对于GUI使用没有能够实现,暴露了本身在这方面不足,需要在以后学习和工作中进行沉入学习提升。在实现功效中还有存在着,对于不含直接左递归文法没法正确找出,提醒错误。在判定是否是LL1文法上还有很大不足,没法使用代码实现当两个FIRST有存在交集判定不是LL1文法功效,这点要求自己对于代码编程能力有着必需提升。这次课程设计使用C++来实现LL1文法分析功效,自己对于C++语言使用有了很大提升。尤其是对于部分C++语法要求,有了很大认识。但存在不足还是比较多。全部是需要在以后学习中认真总结,以使自己能愈加好地语言使用,提升本身技能。这次课程设计总收获是不少。每一次实践全部是提升本身能力机会,在以后生活中,要抓住实践机会,实践是验证真理最好路径。对于一个计算机专业学生来说,更应该重视实践机会,只有实践多了,部分理论知识才能被自己正真认识,不然,值懂理论,没有对于正确性进行验证,还是会有问题,尤其是计算机机器,总存在未知错误,只有不停地探索,才能愈加好地去使用我们工具。指导老师评语学号姓名班级选题名称序号评价内容权重(%)得分1考勤统计、学习态度、工作作风和表现。52自学情况:上网检索机时数、文件阅读情况(笔记)。103论文选题是否优异,是否含有前沿性或前瞻性。54结果验收:是否完成设计任务;能否运行、可操作性怎样等。205汇报格式规范程度、是否图文并茂、语言规范及流畅程度;专题是否鲜明、重心是否突出、叙述是否充足、结论是否正确;是否提出了自己独到见解。306文件引用是否合理、充足、真实。57答辩情况:自我陈说、回复问题正确性、用语正确性、逻辑思维、是否含有独到见解等。25累计指导老师(签章):年月日源码:LL1.h#include<iostream>#include<cstring>#include<cstdlib>#include<fstream>usingnamespacestd;classParser{public:Parser();Parser(constParser&);friendostream&operator<<(ostream&output,constParser&rs);friendistream&operator>>(istream&input,Parser&rs);intFindid(char);intCheck();stringCheckstr(string&);stringDelchar(char,string);intFindchar(char,string);intStrNum(conststring&);charRandChar();stringGetSub(int,conststring&,char);Parser&DelLeft(int);stringFirst(char);stringFirst(conststring&);stringFollow(char);Parser&FirstAndFollow();Parser&CreateTable();~Parser();charPop();intMate(char,char);charTop();charIp();Parser&Push(conststring&);intAnalysis();private:intnum;stringter,non,end,stack,instack;string*content;string*first;string*follow;string**table;};LL1.cpp#include"LL1.h"Parser::Parser(){content=newstring[255];first=newstring[255];follow=newstring[255];table=newstring*[255];}Parser::Parser(constParser&rs){ter=rs.ter;non=rs.non;end=rs.end;num=rs.num;content=newstring[255];first=newstring[255];follow=newstring[255];table=newstring*[255];for(inti=0;i<=num;i++)content[i]=rs.content[i];FirstAndFollow();CreateTable();}ostream&operator<<(ostream&output,constParser&rs){ output<<"文法内容(共"<<rs.num<<"条):"<<endl; inti=0; while(i<rs.num) { output<<rs.content[i++]<<endl; } output<<"结终符:"<<rs.ter<<endl; output<<"非结终符:"<<rs.non<<endl; cout<<"非终止符FIRST集合"<<endl; for(unsignedintj=0;j<rs.non.size();j++) cout<<"FIRST("<<rs.non[j]<<")={"<<rs.first[j]<<"}\t"<<endl; cout<<"非终止符FOLLOW集合"<<endl; for(unsignedintj=0;j<rs.non.size();j++) cout<<"FOLLOW("<<rs.non[j]<<")={"<<rs.follow[j]<<"}\t"<<endl; output<<"估计分析表:"<<endl<<"\t"; for(unsignedintj=0;j<rs.ter.size();j++) output<<rs.ter[j]<<"\t"; output<<"$"<<endl; for(unsignedintj=0;j<rs.non.size();j++) { output<<rs.non[j]<<"\t"; for(unsignedintk=0;k<=rs.ter.size();k++) cout<<rs.table[j][k]<<"\t"; output<<endl; } returnoutput;}istream&operator>>(istream&input,Parser&rs){ unsignedintj=0; charfilename[255]; cout<<"请输入文件名:"; input>>filename; ifstreaminfile(filename,ios::in); if(!infile){ cout<<"无法打开文件!"<<endl; exit(0); } while(1) { unsignedinti=0; infile>>rs.end; rs.content[j++]=rs.end; if(infile.eof())break; while(i<rs.end.size()) { if(rs.end[i]=='|'||rs.end[i]=='^'); elseif(i==1||i==2)i++; elseif(rs.end[i]>='A'&&rs.end[i]<='Z'){ if(std::string::npos==rs.non.find(rs.end[i]))rs.non.append(1,rs.end[i]); } elseif(std::string::npos==rs.ter.find(rs.end[i]))rs.ter.append(1,rs.end[i]); i++; } } rs.num=j-1; if(rs.Check()==0) { exit(0); } rs.FirstAndFollow(); rs.CreateTable(); returninput;}intParser::Findid(chara){inti=0;while(i<num){if(content[i][0]==a)returni;i++;}return-1;}charParser::RandChar(){switch(rand()%3){case0:return'A';case1:return'B';case2:return'C';case3:return'D';}return'D';}intParser::Check(){unsignedintj=0;inti=0;while(i<num){if(content[i].size()<=3){cout<<"文法句"<<content[i]<<"长度不对!"<<endl;return0;}if(content[i][1]!='-'||content[i][2]!='>'){cout<<"文法句"<<content[i]<<"未来使用推导符\"->\"!"<<endl;return0;}intn=StrNum(content[i]);ints=0;charz=content[i][0];intm=0;for(intk=1;k<=n;k++){stringtmp=GetSub(k,content[i],'|');if(z==tmp[0]){s=1;m++;}}if(m==n){cout<<"文法句"<<content[i]<<"将形成无穷推导!"<<endl;return0;}if(s==1)DelLeft(i);i++;}return1;}Parser&Parser::DelLeft(inti){intn=StrNum(content[i]);charc=RandChar();charz=content[i][0];ints=0;for(intk=1;k<=n;k++){stringtmp=GetSub(k,content[i],'|');if(z==tmp[0])s=1;}if(s==0)return*this;cout<<"文法句"<<content[i]<<"含有直接左递归,";while(1){if(Findchar(c,non)==-1)break;elsec=RandChar();}cout<<"随机产生非终止符为:"<<c<<endl;non.append(1,c);stringtemp;temp+=z;temp+="->";stringnext;next+=c;next+="->";for(intk=1;k<=n;k++){stringt=GetSub(k,content[i],'|');if(z==t[0]){t.erase(0,1);t+=c;next+=t;next+='|';}else{if(t=="^")t.clear();t+=c;temp+=t;temp+='|';}}next+='^';temp.erase(temp.size()-1,1);content[i]=temp;num=num+1;content[num]=end;for(intj=num-1;j>i;j--)content[j]=content[j-1];content[i+1]=next;return*this;}stringParser::Checkstr(string&a){unsignedinti=0,j=0;for(;i<a.size();i++){for(j=i+1;j<a.size();j++){if(a[i]==a[j]){a.erase(j,1);}}}returna;}stringParser::Delchar(charx,stringa){intj,i=int(a.size());for(j=0;j<i;j++)if(a[j]==x)a.erase(j,1);returna;}intParser::Findchar(charx,stringa){unsignedinti=0;while(i<a.size()){if(a[i]==x)returni;i++;}return-1;}stringParser::GetSub(inti,conststring&a,charc='|'){stringch;intj[255];intn=1;j[0]=2;if(i>=int(a.size()))returnch;for(unsignedintk=3;k<a.size();k++)if(a[k]==c)j[n++]=k;for(unsignedintk=j[i-1]+1;k<a.size();k++){if(a[k]==c)break;elseif(std::string::npos==ch.find(a[k]))ch.append(1,a[k]);}returnch;}intParser::StrNum(conststring&a){intn=0;for(unsignedinti=3;i<a.size();i++)if(a[i]=='|')n++;returnn+1;}stringParser::First(charx){stringch="";if(Findchar(x,ter)!=-1){ch.append(1,x);ch.append(1,'');}elseif(Findchar(x,non)!=-1){inti=Findid(x);if(i!=-1){stringq=content[i];unsignedintk=3;while(k<q.size()){if(q[k-1]=='|'||k==3){if(Findchar(q[k],ter)!=-1||q[k]=='^'){ch.append(1,q[k]);ch.append(1,'');}else{if(k==3||q[k+1]=='|'||k==q.size()-1)ch+=First(q[k]);else{stringtemp=First(q[k-1]);if(Findchar('^',temp)!=-1)ch+=First(q[k]);}}k++;}elsek++;}}}returnch;}stringParser::First(conststring&a){returnFirst(a[0]);}stringParser::Follow(charx){stringch;if(Findchar(x,non)!=-1){if(!Findid(x)){ch+="$";ch+='';}inti=0;while(i<num){stringq=content[i];unsignedintk=3;charc=content[i][0];while(k<q.size()){while(q[k]==x){if(k<q.size()-1&&q[k+1]!='|'){stringtemp=Delchar('^',First(q[k+1]));if(ch.find(temp)==string::npos)ch+=temp;if(Findchar('^',First(q[k+1]))!=-1){stringfollow_c=Follow(c);if(ch!=follow_c&&ch.find(follow_c)==std::string::npos)ch+=follow_c;}}elseif(k==q.size()-1){stringfollow_c=Follow(c);if(ch.find(follow_c)==std::string::npos)ch+=follow_c;}k++;}k++;}i++;}}returnch;}Parser&Parser::FirstAndFollow(){unsignedinti=0;while(i<non.size()){first[i]=First(non[i]);follow[i]=Follow(non[i]);i++;}return*this;}Parser&Parser::CreateTable(){for(unsignedinti=0;i<=non.size();i++)table[i]=newstring[255];for(unsignedinti=0;i<non.size();i++){stringtemp=content[i];intw=Findchar(temp[0],this->non);intn=StrNum(temp);for(intk=1;k<=n;k++){stringtmp=GetSub(k,temp);stringfir=First(tmp);for(unsignedintj=0;j<fir.size();j++){intidz=Findchar(fir[j],ter);if(idz!=-1)table[w][idz]=tmp;}if(Findchar('^',fir)!=-1||tmp[0]=='^'){stringfol=Follow(temp[0]);for(unsignedintj=0;j<fol.size();j++){intz=Findchar(fol[j],ter);if(z==-1)z=int(ter.size());table[w][z]=tmp;}}}}return*this;}Parser::~Parser(){delete[]content;delete[]first;delete[]follow;delete[]table;}charParser::Pop(){charx=

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论