版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
合肥工業(yè)大學(xué)計(jì)算機(jī)與信息學(xué)院編譯原理實(shí)驗(yàn)報告專業(yè):學(xué)號:姓名:指導(dǎo)老師:完成時間:實(shí)驗(yàn)一詞法分析設(shè)計(jì)實(shí)驗(yàn)?zāi)康耐ㄟ^本實(shí)驗(yàn)的編程實(shí)踐,使學(xué)生了解詞法分析的任務(wù),掌握詞法分析程序設(shè)計(jì)的原理和構(gòu)造方法,使學(xué)生對編譯的基本概念、原理和方法有完整和清楚的理解,并且能夠正確和熟練地運(yùn)用。實(shí)驗(yàn)環(huán)境Windows8.1、VisualStudio2013、C++實(shí)驗(yàn)原理實(shí)驗(yàn)數(shù)據(jù)結(jié)構(gòu)說明 Tablestringstr[40]intstrcountstringname存儲string存儲string的數(shù)目存儲type名Table()~Table()voidsetname(stringstrTemp)stringgetname()voidupdate(stringstrTemp)voidinit(stringfilename)intsearch(stringstrTemp)構(gòu)造函數(shù)析構(gòu)函數(shù)設(shè)置name值獲取name值添加strTemp的值初始化table在table中查詢strTempOutTokenstringvalueinttypeintpointerstringtynameintlineintrow存儲分析單詞的值Type的編號單詞的位置存儲在表中位置分析單詞的行的值分析單詞的列的值OutToken(stringval,intt,intp,stringtn,intl,intr)~OutToken()friendostream&operator<<(ostream&output,OutToken&ot)有參數(shù)構(gòu)造函數(shù)析構(gòu)函數(shù)重載<<函數(shù)TokenAnalyzerTableKeywordTableSeperatorTablesumoperatorTablereloperatorTableconstantTableidentifierOutTokenouttokenType1:C++關(guān)鍵字Type2:分界符Type3:算術(shù)運(yùn)算符Type4:關(guān)系運(yùn)算符Type5:常數(shù)Type6:標(biāo)識符二元式TokenAnalyzer()~TokenAnalyzer()voidinittable()voiddisplay()voidstrsearch(stringstrin,intline,introw)voidreadcode()構(gòu)造函數(shù)析構(gòu)函數(shù)初始化表輸出所有單詞二元式分析strin讀取源代碼實(shí)驗(yàn)算法描述1)詞法分析設(shè)計(jì)流程圖2)詞法分析程序框圖3)統(tǒng)計(jì)字符位置程序框圖實(shí)驗(yàn)內(nèi)容使用C++語言實(shí)現(xiàn)對C++語言字集的源程序進(jìn)行詞法分析。通過輸入源程序從左到右對字符串進(jìn)行掃描和分解,依次輸出各個單詞的內(nèi)部編碼及單詞符號自身值;若遇到錯誤則顯示ERROR,然后跳過錯誤部分繼續(xù)顯示;同時進(jìn)行標(biāo)識符登記符號表的管理。詞法分析設(shè)計(jì)主要工作:從源程序中讀取字符統(tǒng)計(jì)行數(shù)和列數(shù)用于錯誤單詞的定位刪除空格類字符,包括回車、制表符空格按拼寫單詞,并用(內(nèi)碼,屬性)二元式來表示,(屬性值—Token的機(jī)內(nèi)表示)如果發(fā)現(xiàn)錯誤則報告出錯根據(jù)需要是否填寫標(biāo)識符供以后各階段使用單詞的基本分類:關(guān)鍵字:由各程序語言具有的固定意義的標(biāo)識符(保留字例)標(biāo)識符:用以表示各種名字的變量名、數(shù)組名、函數(shù)名常數(shù):任何數(shù)值常數(shù)運(yùn)算符:+、-、*、/關(guān)系運(yùn)算符:<、<=、=、>、>=、<>、|分界符:;、,、(、)、[、]、{、}實(shí)驗(yàn)要求1、編程時注意編程風(fēng)格:空行的使用、注釋的使用、縮進(jìn)的使用等2、標(biāo)識符填寫的符號表需提供給編譯程序的以后各階段使用3、根據(jù)測試數(shù)據(jù)進(jìn)行測試。測試實(shí)例分為三部分:(1)各種合法輸入(2)各種組合輸入(3)有記號組成的句子4、詞法分析程序設(shè)計(jì)要求輸出形式單詞二元序列類型位置(行,列)for(1,for)關(guān)鍵字(1,1)實(shí)驗(yàn)結(jié)果分析代碼分析結(jié)果實(shí)驗(yàn)總結(jié)通過此次實(shí)驗(yàn)的編程實(shí)踐加強(qiáng)了自己對詞法分析的任務(wù)的理解,在一定程度上初步掌握了詞法分析程序設(shè)計(jì)的原理和構(gòu)造,并且在對編譯的基本概念、原理和概念方法有更清楚的認(rèn)識。在實(shí)驗(yàn)過程中自己對詞法分析程序中的算法理解出現(xiàn)了一定的偏差,認(rèn)為其中的標(biāo)識符是程序執(zhí)行之前必須都由自己手動構(gòu)造,導(dǎo)致自己在程序的驗(yàn)收階段出現(xiàn)了問題。事實(shí)上,在詞法分析程序中,若識別的字符串是首字符字母,則在關(guān)鍵字表中查詢是否存在,如果不存在則將新造入標(biāo)識符表中。對于在源代碼中注釋問題,由于本程序是以行為單位從TXT文件中讀取代碼,當(dāng)自己將注釋的判斷程序放置掃描每一行的動作前,導(dǎo)致了添加在有效合法語句后的注釋語句全部被分析為Error,所以之后將判斷注釋的語句放置在以一個單位取字符串之前,當(dāng)某一行的字符串中含有//或/*時,則將其后的字符串全部忽略,即跳出本行的后續(xù)的分析步驟,重新執(zhí)行下一行的代碼讀取和分析操作。八、實(shí)驗(yàn)代碼#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("關(guān)鍵字"); seperator.setname("分界符"); sumoperator.setname("運(yùn)算符"); reloperator.setname("關(guān)系運(yùn)算符"); constant.setname("常數(shù)"); identifer.setname("標(biāo)識符"); 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();}實(shí)驗(yàn)二LL(1)分析文法實(shí)驗(yàn)?zāi)康耐ㄟ^完成預(yù)測分析法的語法分析程序,了解預(yù)測分析法和遞歸子程序法的區(qū)別和聯(lián)系。使學(xué)生了解語法分析的功能,掌握語法分析程序設(shè)計(jì)的原理和構(gòu)造方法,訓(xùn)練學(xué)生掌握開發(fā)應(yīng)用程序的基本方法。有利于提高學(xué)生的專業(yè)素質(zhì),為培養(yǎng)適應(yīng)社會多方面需要的能力。實(shí)驗(yàn)環(huán)境Windows8.1、VisualStudio2013、C++實(shí)驗(yàn)原理實(shí)驗(yàn)數(shù)據(jù)結(jié)構(gòu)說明Stackcharcharstack[30]intcount存儲棧符號存儲的符號個數(shù)Stack()~Stack()voidpush(charch)voidpop()chargettop()voiddisplay()構(gòu)造函數(shù)析構(gòu)函數(shù)將ch壓棧棧頂出棧將棧頂元素彈棧返回打印棧內(nèi)容LLAnalyzercharTerminalSymbol[20]charNonTerminalSymbol[20]charlinechar[20]charrowchar[20]intM[20][20]stringGrammar[20]stringFirstset[20]stringFollowset[20]stackchars終結(jié)符非終結(jié)符M表行表頭M表列表頭狀態(tài)表文法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)構(gòu)造函數(shù)析構(gòu)函數(shù)初始化初始化M表查詢ch返回位置讀取文法存入Grammar中生成字符ch的First集生成字符串strFirst集所有文法生成First集生成字符ch的First集兩字符串不同的符連接字符轉(zhuǎn)換成字符串返回生成所有文法Follow集生成M表查詢字strt返回位置文法分析產(chǎn)生式逆序壓棧實(shí)驗(yàn)算法思想描述LL(1)文法程序框圖實(shí)驗(yàn)內(nèi)容根據(jù)某一文法編制調(diào)試LL(1)分析程序,以便對任何輸入的符號串進(jìn)行分析構(gòu)造預(yù)測分析表,并利用分析表和一個棧來實(shí)現(xiàn)對上述程序設(shè)計(jì)語言的分析程序分析法的功能是利用LL(1)控制程序根據(jù)顯示棧頂內(nèi)容、向前看符號以及LL(1)分析表,對輸入符號串自上而下的分析過程實(shí)驗(yàn)要求1、編程時注意風(fēng)格:空行的使用釋縮進(jìn)等。2、如果遇到錯誤的表達(dá)式,應(yīng)輸出提示信息。3、對下列文法,用LL(1)分析法對任意輸入的符號串進(jìn)行分析(1)E->TG(2)G->+TG|—TG(3)G->ε(4)T->FS(5)S->*FS|/FS(6)S->ε(7)F->(E)(8)F->i輸出格式步驟分析棧剩余輸入串所用產(chǎn)生式動作0#Ei+i*i#初始化實(shí)驗(yàn)結(jié)果(1)構(gòu)建First和Follow集構(gòu)建狀態(tài)轉(zhuǎn)移表MLL(1)分析測試實(shí)例1)正確實(shí)例2)錯誤實(shí)例實(shí)驗(yàn)總結(jié)通過完成預(yù)測LL(1)分析法的語法分析程序,自己了解了預(yù)測分析法和遞歸子程序法的區(qū)別和聯(lián)系。使自己了解了語法分析的功能,掌握語法分析程序設(shè)計(jì)的原理和構(gòu)造方法,并且使自己對基本的程序應(yīng)用的開發(fā)具有更進(jìn)一步的理解。但是在此次編程實(shí)驗(yàn)中,由于自己對First集的構(gòu)建算法理解上出現(xiàn)了一定的失誤,導(dǎo)致前期的實(shí)驗(yàn)中總是達(dá)不到自己預(yù)測的輸出,后通過斷點(diǎn)調(diào)試一步一步找出了程序中的錯誤。八、實(shí)驗(yàn)代碼#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++) { //若為終結(jié)符 if(search(TerminalSymbol,str[k])) { strResult=linkstring(strResult,chartostring(str[k])); break; } //若為非終結(jié)符 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)<<"所用產(chǎn)生式" <<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);}實(shí)驗(yàn)三LR(1)分析法實(shí)驗(yàn)?zāi)康臉?gòu)造LR(1)分析程序,利用它進(jìn)行語法分析,判斷給出的符號串是否為該文法識別的句子,了解LR(K)分析方法是嚴(yán)格的從左向右掃描,和自底向上的語法分析方法。實(shí)驗(yàn)環(huán)境Windows8.1、VisualStudio2013、C++實(shí)驗(yàn)原理實(shí)驗(yàn)數(shù)據(jù)結(jié)構(gòu)CharGetcharNTS[20]charTS[20]stringG[20]非終結(jié)符終結(jié)符文法CharGet()~CharGet()voidReadFile()voidDisplayCG()voidInitChar()intSearchTS(charch);intSearchNTS(charch)charGetTS(intintTS)charGetNTS(intintNTS)stringGetG(intstrno)intSearchChar(chararray[],charch)構(gòu)造函數(shù)析構(gòu)函數(shù)文件中讀取文法打印文法初始化TS查詢ch返回位置NTS查詢ch返回位置將intTS位置TS返回將intNTS位置NTS返回將strno位置G返回查詢ch位置并返回ItemSetstringSet[20]intcount存儲項(xiàng)目組字符串?dāng)?shù)組存儲字符串?dāng)?shù)目ItemSet()~ItemSet()boolSearchIS(stringstr)voidInsertIS(stringstr)intGetCount()stringGetI(intintNO)voidDisplay()ItemSetAddIS(ItemSetis,ItemSetisT)boolCompareI(ItemSetis)構(gòu)造函數(shù)析構(gòu)函數(shù)項(xiàng)目集中str,返回真假將str插入項(xiàng)目集項(xiàng)目集字符串?dāng)?shù)目返回intNO處項(xiàng)目集返回打印項(xiàng)目集不同項(xiàng)目集的連接比較兩個項(xiàng)目集是否同LRAnalyzerTableActionT[20][20]charC[20]stringEG[20]ItemSetI[20]stringCreateNI(stringstr)預(yù)測分析表存儲預(yù)測分析表表頭拓廣文法項(xiàng)目集組項(xiàng)目集中插入strLRAnalyzerTable()~LRAnalyzerTable()voidInitC()intSearchC(charch)voidInitEG()voidDisplayLRT()ItemSetClosureStr(stringstrT)ItemSetClosure(ItemSetis)ItemSetGo(ItemSetis,charch)voidSetI()intSearchEG(stringstr)intSearch(ItemSetarray[],ItemSetis)voidSetT(ItemSetis)voidSetLR()boolLRAnalyzer()構(gòu)造函數(shù)析構(gòu)函數(shù)初始化查詢ch返回位置生成拓廣文法打印預(yù)測分析表求strT的Closureis識別字符后ClosureGo函數(shù)的實(shí)現(xiàn)生成文法所有Closure拓廣查詢str返回位置查詢項(xiàng)目集,返回序號據(jù)項(xiàng)目集生成分析表生成所有項(xiàng)目集分析表LR分析實(shí)驗(yàn)算法思想實(shí)驗(yàn)內(nèi)容對下列文法,用LR(1)分析法對任意輸入的符號串進(jìn)行:(1)E->E+TE+T(2)E->T(3)T->T*F(4)T->F(5)F->(E)(6)F->i實(shí)驗(yàn)要求1、編程時注意風(fēng)格:空行的使用釋縮進(jìn)等。2、如果遇到錯誤的表達(dá)式,應(yīng)輸出提示信息。3、程序輸出格式步驟狀態(tài)棧符號棧輸入串動作說明10#i+i*i#移進(jìn)實(shí)驗(yàn)結(jié)果正確實(shí)例分析(2)錯誤實(shí)例分析實(shí)驗(yàn)總結(jié)通過構(gòu)造LR(1)分析程序,進(jìn)一步理解了LR(1)分析程序的基本步驟,并且?guī)椭俗约簩淖笙蛴覓呙韬妥缘紫蛏系恼Z法分析方法有了新的認(rèn)識。在編程實(shí)踐過程中,本實(shí)驗(yàn)的難點(diǎn)和重點(diǎn)是如何構(gòu)建預(yù)測分析表,而在構(gòu)造預(yù)測分析表之前我們需要明白如何求一個項(xiàng)目集的Closure集和Go函數(shù)的實(shí)現(xiàn)。自己在編寫這一段代碼的過程中出現(xiàn)了一點(diǎn)認(rèn)識上的失誤,因此花費(fèi)了大量的時間,以至于自己不能在指定的時間里完成本實(shí)驗(yàn)。在以后的編程實(shí)驗(yàn)中,自己首先需要理解好相應(yīng)的算法,然后才能夠繼續(xù)下一步的編程實(shí)現(xiàn)。八、實(shí)驗(yàn)代碼#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<<"終結(jié)符為:"<<endl; i=1; while(TS[i]!='') cout<<TS[i++]<<endl; cout<<"非終結(jié)符:"<<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. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 小學(xué)語文滬教版課件教學(xué)課件教學(xué)課件教學(xué)
- 玉溪師范學(xué)院《數(shù)學(xué)文化》2021-2022學(xué)年第一學(xué)期期末試卷
- 玉溪師范學(xué)院《區(qū)域分析與規(guī)劃》2022-2023學(xué)年第一學(xué)期期末試卷
- 文書模板-無房證明
- 家用制冷電器具生產(chǎn)企業(yè)的賬務(wù)處理-記賬實(shí)操
- “能源變革”系列研究二:儲能乘政策之風(fēng)啟航-海通證券
- 龍華區(qū)錦華實(shí)驗(yàn)學(xué)校 第一單元測試2024-2025學(xué)年語文五年級上冊(統(tǒng)編版)
- 2023年氣血循環(huán)機(jī)項(xiàng)目綜合評估報告
- 2023年核電子產(chǎn)品項(xiàng)目綜合評估報告
- 2024屆河北保定一中高考數(shù)學(xué)試題考前指導(dǎo)卷
- 2023年山東青島局屬高中自主招生物理試卷真題(含答案詳解)
- 《搭船的鳥》 第一課時公開課一等獎創(chuàng)新教學(xué)設(shè)計(jì)
- 滴灌安裝工程合同2024年
- 2024年國家開放大學(xué)電大《經(jīng)濟(jì)法律基礎(chǔ)》形成性考核題庫
- 2024考研英語二試題及答案解析
- Unit 4 Section B(2a-2b)課件人教版2024新教材七年級上冊英語
- 2024年德州道路旅客運(yùn)輸駕駛員從業(yè)資格考試題庫
- 基于單片機(jī)的銀行排隊(duì)叫號系統(tǒng)
- 大模型應(yīng)用開發(fā)極簡入門基于GPT-4和ChatGPT
- 應(yīng)急救援人員培訓(xùn)計(jì)劃
- 中考字音字形練習(xí)題(含答案)-字音字形專項(xiàng)訓(xùn)練
評論
0/150
提交評論