合肥工业大学编译原理实验报告_第1页
合肥工业大学编译原理实验报告_第2页
合肥工业大学编译原理实验报告_第3页
合肥工业大学编译原理实验报告_第4页
合肥工业大学编译原理实验报告_第5页
已阅读5页,还剩64页未读 继续免费阅读

下载本文档

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

文档简介

合肥工业大学计算机与信息学院编译原理实验报告专业:学号:姓名:指导老师:完成时间:实验一词法分析设计实验目的通过本实验的编程实践,使学生了解词法分析的任务,掌握词法分析程序设计的原理和构造方法,使学生对编译的基本概念、原理和方法有完整和清楚的理解,并且能够正确和熟练地运用。实验环境Windows8.1、VisualStudio2013、C++实验原理实验数据结构说明 Tablestringstr[40]intstrcountstringname存储string存储string的数目存储type名Table()~Table()voidsetname(stringstrTemp)stringgetname()voidupdate(stringstrTemp)voidinit(stringfilename)intsearch(stringstrTemp)构造函数析构函数设置name值获取name值添加strTemp的值初始化table在table中查询strTempOutTokenstringvalueinttypeintpointerstringtynameintlineintrow存储分析单词的值Type的编号单词的位置存储在表中位置分析单词的行的值分析单词的列的值OutToken(stringval,intt,intp,stringtn,intl,intr)~OutToken()friendostream&operator<<(ostream&output,OutToken&ot)有参数构造函数析构函数重载<<函数TokenAnalyzerTableKeywordTableSeperatorTablesumoperatorTablereloperatorTableconstantTableidentifierOutTokenouttokenType1:C++关键字Type2:分界符Type3:算术运算符Type4:关系运算符Type5:常数Type6:标识符二元式TokenAnalyzer()~TokenAnalyzer()voidinittable()voiddisplay()voidstrsearch(stringstrin,intline,introw)voidreadcode()构造函数析构函数初始化表输出所有单词二元式分析strin读取源代码实验算法描述1)词法分析设计流程图2)词法分析程序框图3)统计字符位置程序框图实验内容使用C++语言实现对C++语言字集的源程序进行词法分析。通过输入源程序从左到右对字符串进行扫描和分解,依次输出各个单词的内部编码及单词符号自身值;若遇到错误则显示ERROR,然后跳过错误部分继续显示;同时进行标识符登记符号表的管理。词法分析设计主要工作:从源程序中读取字符统计行数和列数用于错误单词的定位删除空格类字符,包括回车、制表符空格按拼写单词,并用(内码,属性)二元式来表示,(属性值—Token的机内表示)如果发现错误则报告出错根据需要是否填写标识符供以后各阶段使用单词的基本分类:关键字:由各程序语言具有的固定意义的标识符(保留字例)标识符:用以表示各种名字的变量名、数组名、函数名常数:任何数值常数运算符:+、-、*、/关系运算符:<、<=、=、>、>=、<>、|分界符:;、,、(、)、[、]、{、}实验要求1、编程时注意编程风格:空行的使用、注释的使用、缩进的使用等2、标识符填写的符号表需提供给编译程序的以后各阶段使用3、根据测试数据进行测试。测试实例分为三部分:(1)各种合法输入(2)各种组合输入(3)有记号组成的句子4、词法分析程序设计要求输出形式单词二元序列类型位置(行,列)for(1,for)关键字(1,1)实验结果分析代码分析结果实验总结通过此次实验的编程实践加强了自己对词法分析的任务的理解,在一定程度上初步掌握了词法分析程序设计的原理和构造,并且在对编译的基本概念、原理和概念方法有更清楚的认识。在实验过程中自己对词法分析程序中的算法理解出现了一定的偏差,认为其中的标识符是程序执行之前必须都由自己手动构造,导致自己在程序的验收阶段出现了问题。事实上,在词法分析程序中,若识别的字符串是首字符字母,则在关键字表中查询是否存在,如果不存在则将新造入标识符表中。对于在源代码中注释问题,由于本程序是以行为单位从TXT文件中读取代码,当自己将注释的判断程序放置扫描每一行的动作前,导致了添加在有效合法语句后的注释语句全部被分析为Error,所以之后将判断注释的语句放置在以一个单位取字符串之前,当某一行的字符串中含有//或/*时,则将其后的字符串全部忽略,即跳出本行的后续的分析步骤,重新执行下一行的代码读取和分析操作。八、实验代码#include<iostream>#include<string>#include<fstream>#include<iomanip>usingnamespacestd;classTable{private: stringstr[40]; intstrcount; stringname;public: Table(); ~Table(); voidsetname(stringstrTemp); stringgetname(); voidupdate(stringstrTemp); voidinit(stringfilename); intsearch(stringstrTemp);};Table::Table(){ for(inti=0;i<40;i++) str[i]=""; strcount=0; name="";}Table::~Table(){}voidTable::setname(stringstrTemp){ name=strTemp;}stringTable::getname(){ returnname;}voidTable::update(stringstrTemp){ str[++strcount]=strTemp;}voidTable::init(stringfilename){ stringstrin; ifstreaminfiles(filename); if(!infiles) cout<<"打开"<<filename<<"失败!"<<endl; while(getline(infiles,strin)) update(strin); infiles.close();}intTable::search(stringstrTemp){ for(inti=1;i<=strcount;i++) { if(str[i]==strTemp) returni; } return0;}classOutToken{private: stringvalue; inttype; intpointer; stringtyname; intline; introw;public: OutToken(stringval="",intt=0,intp=0,stringtn="",intl=0,intr=0); ~OutToken(); friendostream&operator<<(ostream&output,OutToken&ot);};OutToken::OutToken(stringval,intt,intp,stringtn,intl,intr){ value=val; type=t; pointer=p; tyname=tn; line=l; row=r;}OutToken::~OutToken(){}ostream&operator<<(ostream&output,OutToken&ot){ if(ot.type!=0) output<<setiosflags(ios::left)<<setw(10)<<ot.value <<"("<<setw(2)<<ot.type<<setw(2)<<","<<setw(2)<<ot.pointer<<setw(10)<<")" <<setw(16)<<ot.tyname <<"("<<ot.line<<","<<ot.row<<")"<<endl; else output<<setiosflags(ios::left)<<setw(10)<<ot.value <<setw(17)<<"ERROR" <<setw(16)<<ot.tyname <<"("<<ot.line<<","<<ot.row<<")"<<endl; returnoutput;}classTokenAnalyzer{private: Tablekeyword; Tableseperator; Tablesumoperator; Tablereloperator; Tableconstant; Tableidentifer; OutTokenouttoken[100]; intoutcount;public: TokenAnalyzer(); ~TokenAnalyzer(); voidinittable(); voiddisplay(); voidstrsearch(stringstrin,intline,introw); voidreadcode();};TokenAnalyzer::TokenAnalyzer(){ keyword.setname("关键字"); seperator.setname("分界符"); sumoperator.setname("运算符"); reloperator.setname("关系运算符"); constant.setname("常数"); identifer.setname("标识符"); outcount=0;}TokenAnalyzer::~TokenAnalyzer(){}voidTokenAnalyzer::inittable(){ seperator.init("seperator.txt"); reloperator.init("reloperator.txt"); sumoperator.init("sumoperator.txt"); constant.init("constant.txt"); keyword.init("keyword.txt");}voidTokenAnalyzer::display(){ for(inti=1;i<=outcount;i++) cout<<outtoken[i];}voidTokenAnalyzer::strsearch(stringstrin,intline,introw){ if((strin[0]>='a'&&strin[0]<='z')||(strin[0]>='a'&&strin[0]<='z')) { if(keyword.search(strin)) outtoken[++outcount]=OutToken(strin,1,keyword.search(strin),keyword.getname(),line,row); else { if(identifer.search(strin)) outtoken[++outcount]=OutToken(strin,6,identifer.search(strin),identifer.getname(),line,row); else { identifer.update(strin); outtoken[++outcount]=OutToken(strin,6,identifer.search(strin),identifer.getname(),line,row); } } } else { if(strin[0]>='0'&&strin[0]<='9') { if(constant.search(strin)) outtoken[++outcount]=OutToken(strin,5,constant.search(strin),constant.getname(),line,row); else { constant.update(strin); outtoken[++outcount]=OutToken(strin,5,constant.search(strin),constant.getname(),line,row); } } else { if(seperator.search(strin)) outtoken[++outcount]=OutToken(strin,2,seperator.search(strin),seperator.getname(),line,row); else { if(reloperator.search(strin)) outtoken[++outcount]=OutToken(strin,4,reloperator.search(strin),reloperator.getname(),line,row); else { if(sumoperator.search(strin)) outtoken[++outcount]=OutToken(strin,4,sumoperator.search(strin),sumoperator.getname(),line,row); else outtoken[++outcount]=OutToken(strin,0,0,"ERROR",line,row); } } } }}voidTokenAnalyzer::readcode(){ ifstreaminfile("code.txt"); if(!infile) cout<<"打开失败!"<<endl; stringstrin; intline; introw; line=0; while(getline(infile,strin)) { line++; row=0; if(strin!="") { stringstrtemp=""; while(strin[0]==''&&strin.length()>1) strin=strin.substr(1,strin.length()); if(strin[0]=='/'&&strin[1]=='/') continue; if(strin=="") strin=""; while(strin!=""&&strin!=strtemp) { row++; if(strin.find("")) strtemp=strin.substr(0,strin.find("")); else strtemp=strin; if(strin[0]=='/'&&strin[1]=='/') continue; strsearch(strtemp,line,row); if(strin.find("")) strin=strin.substr(strin.find("")+1,strin.length()); while(strin[0]==''&&strin.length()>1) strin=strin.substr(1,strin.length()); if(strin=="") strin=""; } } } infile.close();}voidmain(void){ TokenAnalyzerT; T.inittable(); T.readcode(); T.display();}实验二LL(1)分析文法实验目的通过完成预测分析法的语法分析程序,了解预测分析法和递归子程序法的区别和联系。使学生了解语法分析的功能,掌握语法分析程序设计的原理和构造方法,训练学生掌握开发应用程序的基本方法。有利于提高学生的专业素质,为培养适应社会多方面需要的能力。实验环境Windows8.1、VisualStudio2013、C++实验原理实验数据结构说明Stackcharcharstack[30]intcount存储栈符号存储的符号个数Stack()~Stack()voidpush(charch)voidpop()chargettop()voiddisplay()构造函数析构函数将ch压栈栈顶出栈将栈顶元素弹栈返回打印栈内容LLAnalyzercharTerminalSymbol[20]charNonTerminalSymbol[20]charlinechar[20]charrowchar[20]intM[20][20]stringGrammar[20]stringFirstset[20]stringFollowset[20]stackchars终结符非终结符M表行表头M表列表头状态表文法First集Follow集符号栈LLAnalyzer()~LLAnalyzer()voidinit()voidinitM()intsearch(chararray[],charch)voidreadfile()stringgetfirst(charch)stringgetfirststr(stringstr)voidsetfirstset()stringgetfollow(charch)stringlinkstring(stringstr,stringstrt)stringchartostring(charch)voidsetfollow()voidsetM()intsearchstr(stringarray[],stringstrt)boolLanalyzer(stringstrin)voidpushstring(intstrno)构造函数析构函数初始化初始化M表查询ch返回位置读取文法存入Grammar中生成字符ch的First集生成字符串strFirst集所有文法生成First集生成字符ch的First集两字符串不同的符连接字符转换成字符串返回生成所有文法Follow集生成M表查询字strt返回位置文法分析产生式逆序压栈实验算法思想描述LL(1)文法程序框图实验内容根据某一文法编制调试LL(1)分析程序,以便对任何输入的符号串进行分析构造预测分析表,并利用分析表和一个栈来实现对上述程序设计语言的分析程序分析法的功能是利用LL(1)控制程序根据显示栈顶内容、向前看符号以及LL(1)分析表,对输入符号串自上而下的分析过程实验要求1、编程时注意风格:空行的使用释缩进等。2、如果遇到错误的表达式,应输出提示信息。3、对下列文法,用LL(1)分析法对任意输入的符号串进行分析(1)E->TG(2)G->+TG|—TG(3)G->ε(4)T->FS(5)S->*FS|/FS(6)S->ε(7)F->(E)(8)F->i输出格式步骤分析栈剩余输入串所用产生式动作0#Ei+i*i#初始化实验结果(1)构建First和Follow集构建状态转移表MLL(1)分析测试实例1)正确实例2)错误实例实验总结通过完成预测LL(1)分析法的语法分析程序,自己了解了预测分析法和递归子程序法的区别和联系。使自己了解了语法分析的功能,掌握语法分析程序设计的原理和构造方法,并且使自己对基本的程序应用的开发具有更进一步的理解。但是在此次编程实验中,由于自己对First集的构建算法理解上出现了一定的失误,导致前期的实验中总是达不到自己预测的输出,后通过断点调试一步一步找出了程序中的错误。八、实验代码#include<iostream>#include<string>#include<fstream>#include<iomanip>usingnamespacestd;classstack{private: charcharstack[30]; intcount;public: stack(); ~stack(); voidpush(charch); voidpop(); chargettop(); voiddisplays();};stack::stack(){ count=0; for(inti=0;i<30;i++) charstack[i]='';}stack::~stack(){}voidstack::push(charch){ charstack[count++]=ch;}voidstack::pop(){ count--;}charstack::gettop(){ returncharstack[--count];}voidstack::displays(){ inti=0; while(i<count) { cout<<charstack[i++]; } for(i=0;i<12-count;i++) cout<<"";}classLLAnalyzer{private: charTerminalSymbol[20]; charNonTerminalSymbol[20]; charlinechar[20]; charrowchar[20]; intM[20][20]; string Grammar[20]; string Firstset[20]; stringFollowset[20]; stackchars;public: LLAnalyzer(); ~LLAnalyzer(); voidinit(); voidinitM(); intsearch(chararray[],charch); voidreadfile(); stringgetfirst(charch); stringgetfirststr(stringstr); voidsetfirstset(); stringgetfollow(charch); stringlinkstring(stringstr,stringstrt); stringchartostring(charch); voidsetfollow(); voidsetM(); intsearchstr(stringarray[],stringstrt); boolLanalyzer(stringstrin); voidpushstring(intstrno);};LLAnalyzer::LLAnalyzer(){ inti=0; intj=0; for(i=1;i<20;i++) { TerminalSymbol[i]=''; NonTerminalSymbol[i]=''; linechar[i]=''; rowchar[i]=''; Grammar[i]=""; Firstset[i]=""; Followset[i]=""; } for(i=0;i<20;i++) for(j=0;j<20;j++) M[i][j]=-1;}LLAnalyzer::~LLAnalyzer(){}voidLLAnalyzer::init(){ inti=1; intj=1; intl=1; intk; stringstrin=Grammar[l++]; while(strin!="") { if(search(NonTerminalSymbol,strin[0])==0) NonTerminalSymbol[i++]=strin[0]; strin=strin.substr(3,strin.length()); for(k=0;k<int(strin.length());k++) { if(strin[k]>='A'&&strin[k]<='Z') { if(search(NonTerminalSymbol,strin[k])==0) NonTerminalSymbol[i++]=strin[k]; } else { if(strin[k]=='|') continue; if(search(TerminalSymbol,strin[k])==0) TerminalSymbol[j++]=strin[k]; } } strin=Grammar[l++]; }}voidLLAnalyzer::initM(){ inti=1; intj=1; while(NonTerminalSymbol[i]!='') { rowchar[i]=NonTerminalSymbol[i++]; } i=1; while(TerminalSymbol[i]!='') { if(TerminalSymbol[i]!='^') linechar[j++]=TerminalSymbol[i++]; else i++; } linechar[j]='#';}intLLAnalyzer::search(chararray[],charch){ inti; for(i=1;i<20;i++) if(array[i]==ch) returni; return0;}voidLLAnalyzer::readfile(){ inti=1; ifstreaminfile("Grammar.txt"); if(!infile) cout<<"Cann'topentheGrammar!"<<endl; else { stringstrin; stringstrsave; while(getline(infile,strin)) { while(strin.find('|')!=-1) { strsave=strin.substr(0,strin.find('|')); Grammar[i++]=strsave; strsave=strin.substr(strin.find('|')+1,strin.length()); strin=strin.substr(0,3); strin=strin+strsave; } Grammar[i++]=strin; } } infile.close();}stringLLAnalyzer::getfirst(charch){ stringstrResult=""; if(search(TerminalSymbol,ch)!=0) strResult+=ch; else { inti=1; while(Grammar[i]!="") { stringstr=Grammar[i]; if(str[0]==ch) { str=str.substr(3,str.length()); if(search(TerminalSymbol,str[0])!=0) strResult+=str[0]; else { for(intj=0;j<int(str.length());j++) { stringstrt=getfirst(str[j]); if(strt.find('^')!=-1) { intk=strt.find('^'); if(k==strt.length()-1) strt=strt.substr(0,strt.length()-1); else { stringstrte=str.substr(0,strt.find('^')); strt=strte+strt.substr(strt.find('^')+1,strt.length()); } strResult+=strt; if(j==str.length()-1) strResult+="^"; } else { strResult+=strt; break; } } } } i++; } } returnstrResult;}stringLLAnalyzer::getfirststr(stringstr){ stringstrte; stringstrResult=""; for(intk=0;k<int(str.length());k++) { //若为终结符 if(search(TerminalSymbol,str[k])) { strResult=linkstring(strResult,chartostring(str[k])); break; } //若为非终结符 else { strte=Firstset[search(NonTerminalSymbol,str[k])]; if(strte[strte.length()-1]=='^') { strte=strte.substr(0,strte.length()-1); strResult=linkstring(strResult,strte); if(k==str.length()-1) strResult=linkstring(strResult,"^"); } else { strResult=linkstring(strResult,strte); break; } } } returnstrResult;}voidLLAnalyzer::setfirstset(){ inti=1; intlocal=0; while(NonTerminalSymbol[i]!='') { local=search(NonTerminalSymbol,NonTerminalSymbol[i]); Firstset[local]=getfirst(NonTerminalSymbol[i]); i++; }}stringLLAnalyzer::getfollow(charch){ stringstrResult=""; if(ch==NonTerminalSymbol[1]) strResult=linkstring(strResult,"#"); inti=1; while(Grammar[i]!="") { stringstr=Grammar[i]; if(str.find(ch,3)!=-1) { intj=str.find(ch,3); if(j<int(str.length())) { stringstrt; stringstrte; strt=str.substr(j+1,strt.length()-1); strte=getfirststr(strt); if(strte=="") { if(str[0]!=ch) strResult=linkstring(strResult,getfollow(str[0])); } else { if(strte[strte.length()-1]=='^') { strte=strte.substr(0,strte.length()-1); strResult=linkstring(strResult,strte); if(str[0]!=ch) strResult=linkstring(strResult,getfollow(strt[0])); } else strResult=linkstring(strResult,strte); } } } i++; } returnstrResult;}stringLLAnalyzer::linkstring(stringstr,stringstrt){ boolflag=true; for(inti=0;i<int(strt.length());i++) { for(intj=0;j<int(str.length());j++) { if(str[j]==strt[i]) { flag=false; break; } } if(flag) str+=strt[i]; } returnstr;}stringLLAnalyzer::chartostring(charch){ stringstrtemp=""; returnstrtemp+ch;}voidLLAnalyzer::setfollow(){ inti=1; intlocal=0; while(NonTerminalSymbol[i]!='') { local=search(NonTerminalSymbol,NonTerminalSymbol[i]); Followset[local]=getfollow(NonTerminalSymbol[i]); i++; }}voidLLAnalyzer::setM(){ intline=0; introw=0; inti=1; stringstrt=""; stringstrtFi=""; stringstrtFl=""; stringstr=""; while(Grammar[i]!="") { strt=Grammar[i]; str=strt.substr(3,strt.length()-3); strtFi=getfirststr(str); intj=0; while(j<int(strtFi.length())) { line=search(rowchar,strt[0]); //First if(strtFi[j]!='^') { row=search(linechar,strtFi[j]); M[line][row]=i; } //Follow else { strtFl=Followset[search(NonTerminalSymbol,strt[0])]; intk=0; while(k<int(strtFl.length())) { row=search(linechar,strtFl[k]); stringstrtem=linkstring(chartostring(strt[0]),"->^"); M[line][row]=searchstr(Grammar,strtem); k++; } } j++; } i++; }}intLLAnalyzer::searchstr(stringarray[],stringstrt){ inti; for(i=1;i<20;i++) if(array[i]==strt) returni; return0;}boolLLAnalyzer::Lanalyzer(stringstrin){ charch; intl; intr; intstep=0; cout<<setiosflags(ios::left)<<setw(12)<<"步骤" <<setw(12)<<"符号栈" <<setw(12)<<"剩余输入串" <<setw(18)<<"所用产生式" <<setw(12)<<"动作"<<endl; chars.push('#'); chars.push(NonTerminalSymbol[1]); while(strin.length()>0) { cout<<setw(12)<<step; chars.displays(); cout<<setw(12)<<strin; ch=chars.gettop(); if(ch=='#'&&strin[0]=='#') { cout<<endl; returntrue; } else { if(ch==strin[0]) strin=strin.substr(1,strin.length()-1); else { l=search(rowchar,ch); r=search(linechar,strin[0]); if(M[l][r]==-1) { cout<<"原符号串语法有误!"<<endl; returnfalse; } pushstring(M[l][r]); } } cout<<endl; step++; } cout<<endl; returnfalse;}voidLLAnalyzer::pushstring(intstrno){ stringstr=Grammar[strno]; intleng=str.length()-1; cout<<setw(18)<<str; while(str[leng]!='>') { if(str[leng]=='^') { cout<<"POP"; break; } else { if(leng==str.length()-1) cout<<"POP,PUSH("; cout<<str[leng]; chars.push(str[leng--]); if(str[leng]=='>') cout<<")"; } }}voidmain(void){ LLAnalyzerl; l.readfile(); l.init(); l.initM(); l.setfirstset(); l.setfollow(); l.setM(); stringstrin; cout<<"Enterthestringyouwanttoanalyze!"<<endl; cin>>strin; strin=strin+"#"; l.Lanalyzer(strin);}实验三LR(1)分析法实验目的构造LR(1)分析程序,利用它进行语法分析,判断给出的符号串是否为该文法识别的句子,了解LR(K)分析方法是严格的从左向右扫描,和自底向上的语法分析方法。实验环境Windows8.1、VisualStudio2013、C++实验原理实验数据结构CharGetcharNTS[20]charTS[20]stringG[20]非终结符终结符文法CharGet()~CharGet()voidReadFile()voidDisplayCG()voidInitChar()intSearchTS(charch);intSearchNTS(charch)charGetTS(intintTS)charGetNTS(intintNTS)stringGetG(intstrno)intSearchChar(chararray[],charch)构造函数析构函数文件中读取文法打印文法初始化TS查询ch返回位置NTS查询ch返回位置将intTS位置TS返回将intNTS位置NTS返回将strno位置G返回查询ch位置并返回ItemSetstringSet[20]intcount存储项目组字符串数组存储字符串数目ItemSet()~ItemSet()boolSearchIS(stringstr)voidInsertIS(stringstr)intGetCount()stringGetI(intintNO)voidDisplay()ItemSetAddIS(ItemSetis,ItemSetisT)boolCompareI(ItemSetis)构造函数析构函数项目集中str,返回真假将str插入项目集项目集字符串数目返回intNO处项目集返回打印项目集不同项目集的连接比较两个项目集是否同LRAnalyzerTableActionT[20][20]charC[20]stringEG[20]ItemSetI[20]stringCreateNI(stringstr)预测分析表存储预测分析表表头拓广文法项目集组项目集中插入strLRAnalyzerTable()~LRAnalyzerTable()voidInitC()intSearchC(charch)voidInitEG()voidDisplayLRT()ItemSetClosureStr(stringstrT)ItemSetClosure(ItemSetis)ItemSetGo(ItemSetis,charch)voidSetI()intSearchEG(stringstr)intSearch(ItemSetarray[],ItemSetis)voidSetT(ItemSetis)voidSetLR()boolLRAnalyzer()构造函数析构函数初始化查询ch返回位置生成拓广文法打印预测分析表求strT的Closureis识别字符后ClosureGo函数的实现生成文法所有Closure拓广查询str返回位置查询项目集,返回序号据项目集生成分析表生成所有项目集分析表LR分析实验算法思想实验内容对下列文法,用LR(1)分析法对任意输入的符号串进行:(1)E->E+TE+T(2)E->T(3)T->T*F(4)T->F(5)F->(E)(6)F->i实验要求1、编程时注意风格:空行的使用释缩进等。2、如果遇到错误的表达式,应输出提示信息。3、程序输出格式步骤状态栈符号栈输入串动作说明10#i+i*i#移进实验结果正确实例分析(2)错误实例分析实验总结通过构造LR(1)分析程序,进一步理解了LR(1)分析程序的基本步骤,并且帮助了自己对从左向右扫描和自底向上的语法分析方法有了新的认识。在编程实践过程中,本实验的难点和重点是如何构建预测分析表,而在构造预测分析表之前我们需要明白如何求一个项目集的Closure集和Go函数的实现。自己在编写这一段代码的过程中出现了一点认识上的失误,因此花费了大量的时间,以至于自己不能在指定的时间里完成本实验。在以后的编程实验中,自己首先需要理解好相应的算法,然后才能够继续下一步的编程实现。八、实验代码#include<iostream>#include<fstream>#include<string>#include<iomanip>usingnamespacestd;voidDisplayCS(chararray[],intintS){ inti; for(i=1;i<=intS;i++) cout<<setw(3)<<array[i]; for(i=1;i<=(6-intS);i++) cout<<setw(3)<<"";}voidDisplayIS(intarray[],intintS){ inti; for(i=1;i<=intS;i++) cout<<setw(3)<<array[i]; for(i=1;i<=(6-intS);i++) cout<<setw(3)<<"";}classCharGet{private: charNTS[20]; charTS[20]; stringG[20]; intSearchChar(chararray[],charch);public: CharGet(); ~CharGet(); voidReadFile(); voidDisplayCG(); voidInitChar(); intSearchTS(charch); intSearchNTS(charch); charGetTS(intintTS); charGetNTS(intintNTS); stringGetG(intstrno);};CharGet::CharGet(){ inti=0; for(i=0;i<20;i++) { NTS[i]=''; TS[i]=''; G[i]=""; }}CharGet::~CharGet(){}voidCharGet::ReadFile(){ inti=1; stringstrin=""; stringstrsave=""; ifstreaminfile("Grammar.txt"); if(!infile) cout<<"Cann'topentheGrammar.txt!"<<endl; else { while(getline(infile,strin)) { while(strin.find('|')!=-1) { strsave=strin.substr(0,strin.find('|')); G[i++]=strsave; strsave=strin.substr(strin.find('|')+1,strin.length()); strin=strin.substr(0,3); strin=strin+strsave; } G[i++]=strin; } } infile.close();}voidCharGet::DisplayCG(){ cout<<"输入的文法为:"<<endl; inti=1; while(G[i]!="") cout<<G[i++]<<endl; cout<<"终结符为:"<<endl; i=1; while(TS[i]!='') cout<<TS[i++]<<endl; cout<<"非终结符:"<<endl; i=1; while(NTS[i]!='') cout<<NTS[i++]<<endl;}intCharGet::SearchChar(chararray[],charch){ inti=1; while(array[i]!='') { if(array[i]==ch) returni; i++; } return0;}intCharGet::SearchTS(charch){ returnSearchChar(TS,ch);}intCharGet::SearchNTS(charch){ returnSearchChar(NTS,ch);}voidCharGet::InitChar(){ intintG=1; intintNTS=1; intintTS=1; intintStr=0; stringstr=""; while(G[intG]!="") { str=G[intG++]; if(SearchChar(NTS,str[0])==0) NTS[intNTS++]=str[0]; str=str.substr(3,str.length()-3); for(intStr=0;intStr<int(str.length());intStr++) { if(str[intStr]<='Z'&&str[intStr]>='A') continue; else { if(SearchChar(TS,str[intStr])==0) TS[intTS++]=str[intStr]; else continue; } } }}charCharGet::GetTS(intintTS){ returnTS[intTS];}charCharGet::GetNTS(intintNTS){ returnNTS[intNTS];}stringCharGet::GetG(intstrno){ returnG[strno];}classItemSet{private: stringSet[20]; intcount;public: ItemSet(); ~ItemSet(); boolSearchIS(stringstr); voidInsertIS(stringstr); intGetCount(); stringGetI(intintNO); voidDisplay(); ItemSetAddIS(ItemSetis,ItemSetisT); boolCompareI(ItemSetis);};ItemSet::ItemSet(){ for(inti=0;i<20;i++) Set[i]=""; count=1;}ItemSet::~ItemSet(){}boolItemSet::SearchIS(stringstr){ intintS=1; while(Set[intS]!="") { if(Set[intS++]==str) returntrue; } returnfalse;}voidItemSet::InsertIS(stringstr){ if(!SearchIS(str)&&str!="") Set[count++]=str;}intItemSet::GetCount(){ returncount-1;}stringItemSet::GetI(intintNo){ returnSet[intNo];}voidItemSet::Display(){ intintS=1; for(intS=1;intS<count;intS++) cout<<Set[intS]<<endl;}ItemSetItemSet::AddIS(ItemSetis,ItemSetisT){ ItemSetisTemp=isT; intintIS=1; while(intIS<count) isTemp.InsertIS(is.GetI(intIS++)); returnisTemp;}boolItemSet::CompareI(ItemSetis){ stringstr=""; stringstr1=""; intj=0; intintIS=1; if(this->GetCount()!=is.GetCount()) returnfalse; while(is.GetI(intIS)!="") { for(inti=1;i<=this->GetCount();i++) { if(this->Set[i]==is.GetI(intIS)) break; else { str=this->Set[i]; str1=is.GetI(intIS); j=this->GetCount(); if(i==this->GetCount()&&this->Set[i]!=is.GetI(intIS)) returnfalse; } } intIS++; } returntrue;}structAction{ charAct; intState;};classLRAnalyzerTable:publicCharGet{private: ActionT[20][20]; charC[20]; stringEG[20]; ItemSetI[20]; stringCreateNI(stringstr);public: LRAnalyzerTable(); ~LRAnalyzerTable(); voidInitC(); intSearchC(charch); voidInitEG(); voidDisplayLRT(); ItemSetClosureStr(stringstrT); ItemSetClosure(ItemSetis); ItemSetGo(ItemSetis,charch); voidSetI(); intSearchEG(stringstr); intSearch(ItemSetarray[],ItemSetis); voidSetT(ItemSetis); voidSetLR(); boolLRAnalyzer();};LRAnalyzerTable::LRAnalyzerTable(){ inti=0; intj=0; for(i=0;i<20;i++) { for(j=0;j<20;j++) { T[i][j].Act=''; T[i][j].State=-1; } C[i]=''; EG[i]=""; }}LRAnalyzerTable::~LRAnalyzerTable(){}stringLRAnalyzerTable::CreateNI(stringstr){ stringstrResult=""; stringstrTemp=str; if(strTemp.find('.')==-1) { strResult=strTemp.substr(0,3); strResult+="."; strResult+=strTemp.substr(3,int(strTemp.length())-3); } else { if(strTemp.find('.')==int(strTemp.length())-1) strResult=""; else { strResult=strTemp.substr(0,strTemp.find('.')); strResult+=strTemp[strTemp.find('.')+1]; strResult+="."; strResult+=strTemp.substr(strTemp.find('.')+2,strTemp.length()); } } returnstrResult;}voidLRAnalyzerTable::InitC(){ intintTemp=1; intintC=1; while(GetTS(intTemp)!='') C[intC++]=GetTS(intTemp++); C[intC++]='#'; intTemp=1; while(GetNTS(intTemp)!='') C[intC++]=GetNTS(intTemp++);}intLRAnalyzerTable::SearchC(charch){ intintC=1; while(C[intC]!='') { if(C[intC]==ch) returnintC; intC++; } return0;}voidLRAnalyzerTable::InitEG(){ intintEG=1; intintG=1; stringstrG=GetG(intG); strG=strG.substr(0,1); EG[intEG++]="S->"+strG; while(GetG(intG)!="") { EG[intEG++]=GetG(intG++); }}voidLRAnalyzerTable::DisplayLRT(){ inti=0; intj=0; for(i=0;i<12;i++) cout<<setw(3)<<""<<C[i]; cout<<endl; for(i=0;i<12;i++) { cout<<setw(2)<<i<<""; for(j=1;j<9;j++) { if(T[i][j].Act=='') cout<<setw(2)<<""; else cout<<setw(2)<<T[i][j].Act; if(T[i][j].State==-1) cout<<setw(2)<<""; else cout<<setw(2)<<T[i][j].State; } cout<<endl; }}ItemSetLRAnalyzerTable::ClosureStr(stringstrT){ ItemSetisTemp; isTemp.InsertIS(strT); intintIST=1; intintL=strT.find('.'); intintG=1; stringstrTemp=strT; while(intIST<=isTemp.GetCount()) { strTemp=isTemp.GetI(intIST); intL=strTemp.find('.'); if(intL<int(strTemp.length())-1&&SearchNTS(strTemp[intL+1])!=0) { intG=1; while(GetG(intG)!="") { if(GetG(intG)[0]==strTemp[intL+1]) { isTemp.InsertIS(CreateNI(GetG(intG))); } intG++; } } intIST++; } returnisTemp;}ItemSetLRAnalyzerTable::Closure(ItemSetis){ ItemSetisTemp; intintIS=1; stringstr=""; while(intIS<=is.GetCount()) { str=is.GetI(intIS++); isTemp=isTemp.AddIS(isTemp,ClosureStr(str)); } returnisTemp;}ItemSetLRAnalyzerTable::Go(ItemSetis,charch){ ItemSetisTemp; stringstrT=""; intintIS=1; intintL=-1; while(intIS<=is.GetCount()) { strT=is.GetI(intIS); intL=strT.find('.'); if(intL==strT.length()-1) break; else { if(strT[intL+1]==ch) { isTemp.InsertIS(CreateNI(strT)); } } intIS++; } returnClosure(isTemp);}voidLRAnalyzerTable::SetI(){ intintN=0; intintI=0; intintC=1; ItemSetis; I[intI]=ClosureStr(CreateNI(EG[1])); while

温馨提示

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

评论

0/150

提交评论