編譯原理課程設(shè)計報告_第1頁
編譯原理課程設(shè)計報告_第2頁
編譯原理課程設(shè)計報告_第3頁
編譯原理課程設(shè)計報告_第4頁
編譯原理課程設(shè)計報告_第5頁
已閱讀5頁,還剩39頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、編譯原理課程設(shè)計報告 課 程 設(shè) 計 報 告 設(shè)計題目:一個簡單文法的編譯器的設(shè)計與實(shí)現(xiàn) 班 級:計算機(jī)1206班 組長學(xué)號:2012XXX 組長姓名:XXX 指導(dǎo)教師:XXX 設(shè)計時間:2014年12月 設(shè)計分工 組長學(xué)號及姓名:2012XXX XXX 分工:1)讀取源文件進(jìn)行詞法分析 2)進(jìn)行LL(1)分析生成分析表 3)設(shè)計頂層自動機(jī)將源程序分段 4)生成可執(zhí)行的匯編程序 組員1學(xué)號及姓名:2012XXXXXX 分工:1)設(shè)計第二層自動機(jī)處理程序片段 2)生成中間語言四元式 3)源程序錯誤處理 組員2學(xué)號及姓名:2012XXXXXX 分工:1)設(shè)計第三層自動機(jī)處理復(fù)合表達(dá)式 2)設(shè)計帶動

2、作的LL(1) 文法 3)源程序錯誤處理摘 要編譯原理課程具有很強(qiáng)的理論性和實(shí)踐性,是計算機(jī)專業(yè)的一門非常重要的專業(yè)基礎(chǔ)課程,在系統(tǒng)軟件中也是占有十分重要的地位。本次課程設(shè)計我們是在Visual C+的平臺上應(yīng)用了詞法分析、語法分析、語義分析、中間語言生成以及目標(biāo)語言生成的知識設(shè)計了一個簡單的編譯器前端。其中設(shè)計了一個簡單的有限自動機(jī)來掃描源程序即進(jìn)行語法分析,并生成了關(guān)鍵字表、標(biāo)志符表、界符表、常數(shù)表和Token串;設(shè)計了一個LL(1)文法和一個帶動作的文法來實(shí)現(xiàn)語法分析,并生成了Select集和LL(1)分析表;采用了四元式序列的設(shè)計來生成中間語言;通過匯編語言設(shè)計來生成目標(biāo)語言。最后為了

3、使該編譯器更加完善,我們設(shè)計了簡單的的錯誤檢查機(jī)制,能夠?qū)υ闯绦蜻M(jìn)行比較全面的錯誤檢查同時也能夠指出錯誤出現(xiàn)的大致位置,增強(qiáng)了該編譯器的健壯性。關(guān)鍵字:編譯器,前端,有限自動機(jī),LL(1)文法,匯編語言,錯誤處理目 錄 摘要31、概述52、課程設(shè)計任務(wù)及要求52.1設(shè)計任務(wù)52.2設(shè)計要求63、算法與數(shù)據(jù)結(jié)構(gòu)63.1詞法分析器的算法63.2 語法分析器的算法12 3.2.1 LL(1)文法設(shè)計算法12 3.2.2遞歸下降子程序設(shè)計算法193.3中間語言生成器算法203.4處理復(fù)合表達(dá)式算法24 3.5目標(biāo)語言生成器算法30 3.6數(shù)據(jù)結(jié)構(gòu)394、程序設(shè)計與實(shí)現(xiàn)394.1編譯程序設(shè)計與實(shí)現(xiàn)39

4、4.2程序?qū)嶒?yàn)結(jié)果39 4.2.1待測源程序39 4.2.2詞法分析結(jié)果40 4.2.3語法分析結(jié)果41 4.2.4中間語言生成結(jié)果42 4.2.5目標(biāo)語言生成結(jié)果43 4.2.6程序錯誤處理結(jié)果445、參考文獻(xiàn)441、概述本次課程設(shè)計的編譯程序主要包括了詞法分析器、語法分析器、中間代碼生成器和目標(biāo)代碼生成器四部分,編譯程序的輸出結(jié)果包括了詞法分析后的關(guān)鍵字表、界符表、標(biāo)識符表和Token串,語法分析后的Select集和LL(1)分析表;中間代碼生成器產(chǎn)生的四元式序列。最后除了完成設(shè)計所要求的內(nèi)容之外,我們還做了一些擴(kuò)展例如:設(shè)計了目標(biāo)代碼生成器來生成可執(zhí)行的匯編程序;還設(shè)計了錯誤檢查機(jī)制來查

5、找源程序的錯誤并指出錯誤產(chǎn)生的大致位置。詞法分析是編譯程序的第一步操作,它的任務(wù)是:從左至右掃描源程序的字符串,按照一定的詞法規(guī)則識別出一個個正確的字符,并轉(zhuǎn)換成該字符相對應(yīng)的Token碼,最終生成一個完整的Token串以供語法分析使用。由此可知,詞法分析是整個編譯程序的基礎(chǔ),而執(zhí)行詞法分析的一系列操作的就是詞法分析器。語法分析是編譯程序的第二步操作也是編譯程序的核心部分,其主要任務(wù)是:分析語法內(nèi)容,確定語法結(jié)構(gòu)同時生成Select集和LL(1)分析表。中間代碼和目標(biāo)代碼的生成是對源程序的進(jìn)一步操作,其任務(wù)是:根據(jù)詞法分析產(chǎn)生的Token串和語法分析確定的語法結(jié)構(gòu)來生成中間語言四元式和目標(biāo)語言

6、匯編語言程序。2、課程設(shè)計任務(wù)及要求 2.1設(shè)計任務(wù) 一個簡單文法的編譯器前端的設(shè)計與實(shí)現(xiàn)l 定義一個簡單程序設(shè)計語言文法(包括變量說明語句、算術(shù)運(yùn)算表達(dá)式、賦值語句;擴(kuò)展包括邏輯運(yùn)算表達(dá)式、If語句、While語句等);l 掃描器設(shè)計實(shí)現(xiàn);l 語法分析器設(shè)計實(shí)現(xiàn);l 中間代碼設(shè)計;l 中間代碼生成器設(shè)計實(shí)現(xiàn)。 l 目標(biāo)代碼生成器設(shè)計實(shí)現(xiàn) 2.2設(shè)計要求l 給出一個源程序文件,作為編譯器前端的輸入l 輸出相關(guān)編譯階段的運(yùn)行結(jié)果l 詞法分析階段:l 生成Token序列;l 生成關(guān)鍵字表、界符表、符號表系統(tǒng)。l 中間代碼生成階段:l 生成四元式序列;l 生成符號表系統(tǒng)。3、 算法與數(shù)據(jù)結(jié)構(gòu) 3.1

7、詞法分析器的算法 1)一個簡單有限自動機(jī)(掃描器)的設(shè)計:n?d-dd.dd-=-#-d 其中: (字母),d(數(shù)字),#(源程序結(jié)束符) (2)?(空格,回車,換行)需要濾掉 (3)(泛指單詞的后繼附) (4)(表示省略了其他界符的處理)2)一個簡單詞法分析器設(shè)計:開始結(jié)束調(diào)用識別器關(guān)鍵字/標(biāo)識符算術(shù)常數(shù)結(jié)束符#查KT表查到查填I(lǐng)T表查填CT表常數(shù)處理C.TOKEN查PT表P.TOKENI.TOKENK.TOKENyn查到ere:非法界符ynyynnny 算法實(shí)現(xiàn)如下:Void main() /詞法分析部分代碼 char p10;string TOKEN;string Source;stri

8、ng temp;FILE* fp;fp=fopen("D:MySourceFile.txt","r");if(!fp) Source="Cannot open file"elseint i;char c;while(!feof(fp)c=fgetc(fp);Source+=c;fclose(fp);for(i=0;i<Source.size();i+)if(Sourcei=13|Sourcei=9|Sourcei=10|Sourcei=-1)Source.replace(i,1," ");Source+=&#

9、39;#'cout<<"處理后源程序n"<<Source<<endl<<endl;initKTPT();int i,j;for(i=0;i<Source.size();i+)switch(kindofchar(Sourcei)case 'e':cout<<"n非法字符!,位置:"<<i<<"錯誤代碼"<<Sourcei<<endl<<endl;for(int k=0;k<=i;k+

10、) cout<<Sourcek;exit(0);case 's':break;case 'd':temp+=Sourcei;for(j=1;Sourcei+j='.'|kindofchar(Sourcei+j)='d'j+) temp+=Sourcei+j;i=i+j-1;if(inCT(temp)=-1)temp="N "+temp;CT.push_back(temp);TOKEN+="<CT,"itoa(inCT(temp),p,10);TOKEN+=p;TOKEN+=

11、">"temp=""break;case 'w':temp+=Sourcei;for(j=1;kindofchar(Sourcei+j)='w'|kindofchar(Sourcei+j)='d'|Sourcei+j='_'j+) temp+=Sourcei+j;i=i+j-1;if(inKT(temp)!=-1)TOKEN+="<KT,"itoa(inKT(temp),p,10);TOKEN+=p;TOKEN+=">"temp=&q

12、uot;"break;if(inIT(temp)=-1) IT.push_back(temp);TOKEN+="<IT,"itoa(inIT(temp),p,10);TOKEN+=p;TOKEN+=">"temp=""break;case 'f':temp+=Sourcei;if(kindofchar(Sourcei+1)='f'&&inPT(temp+Sourcei+1)>=0)temp+=Sourcei+1;i+;TOKEN+="<PT,&

13、quot;itoa(inPT(temp),p,10);TOKEN+=p;TOKEN+=">"temp=""break;case '"':i+;for(j=0;Sourcei+j!='"'&&(i+j)<(Source.size()-1);j+)if(Sourcei+j=''&&Sourcei+j+1='"')temp+='"'j+;if(Sourcei+j=''&&am

14、p;Sourcei+j+1=''')temp+='''j+;if(Sourcei+j=''&&Sourcei+j+1='')temp+=''j+;if(Sourcei+j=''&&Sourcei+j+1='0')temp+='0'j+;else temp+=Sourcei+j;if(i+j)>=(Source.size()-1)cout<<"未找到可匹配的雙引號,位置:"<&l

15、t;i<<endl;for(int k=0;k<=i;k+) cout<<Sourcek;exit(0);i=i+j;if(inCT(temp)=-1)temp="S "+temp;CT.push_back(temp);TOKEN+="<CT,"itoa(inCT(temp),p,10);TOKEN+=p;TOKEN+=">"temp=""break;case ''':if(i+3)<(Source.size()-1)&&Sou

16、rcei+1=''&&Sourcei+3=''')switch(Sourcei+2)case '':temp+=''break;case ''':temp+='''break;case '"':temp+='"'break;case '0':temp+="0"break;default:cout<<"錯誤的單引號使用(轉(zhuǎn)義錯誤),位置:"&l

17、t;<i<<endl;for(int k=0;k<=i;k+) cout<<Sourcek;exit(0);i+=3;elseif(i+2)>=(Source.size()-1)cout<<"錯誤的單引號使用(越界),位置:"<<i<<endl;for(int k=0;k<=i;k+) cout<<Sourcek;exit(0);temp+=Sourcei+1;i+=2;if(inCT(temp)=-1)temp="C "+temp;CT.push_back(

18、temp);TOKEN+="<CT,"itoa(inCT(temp),p,10);TOKEN+=p;TOKEN+=">"temp=""break;case '#':break;default:break;3.2語法分析器的算法首先介紹一下整個課程設(shè)計中我們使用到的一些文法。C-文件 -> void main ( ) C<-程序體àC -> Y<-語句-> Y -> S<-聲明語句-> ; I<-語句后繼->| Z<-賦值語句->

19、; ; I| V<-條件語句->N<-if后繼->B I| W<-循環(huán)語句-> II->Y | 空S ->類型 標(biāo)識符 聲明后繼類型 -> int|float|char聲明后繼 -> ,標(biāo)識符 聲明后繼 | 空Z -> 標(biāo)識符 = 表達(dá)式V -> if ( E )C N->else C | 空W -> while ( 表達(dá)式 )程序體E -> 詳見rull.txt源文件。語法分析主要是對LL(1)文法和遞歸下降子程序的設(shè)計,其算法設(shè)計如下:3.2.1 LL(1)文法的設(shè)計1)算法原理如下:l 利用一個分析

20、表,登記如何選擇產(chǎn)生式的知識;l 利用一個分析棧,記錄分析過程;l 此分析法要求文法必須滿足 LL(1)文法形式。# Z開始:棧 ; NEXT(w)2) 算法設(shè)計如下: 重復(fù)執(zhí)行 、 ,直到棧中只剩 # 為止: (1) (2) 若 棧頂符=A 且 當(dāng)前符 w=a 且 有產(chǎn)生式: Aàaa, 則 POP,PUSH(aa)R ; 若 棧頂符=a 且 當(dāng)前符為a; 則 pop,NEXT(w); 否則,錯誤處理!#棧結(jié)束:;當(dāng)前符 w= # (3)算法實(shí)現(xiàn)如下:void maketable()/需要參數(shù)指明所需文法/打開文件/switch()/根據(jù)參數(shù)選擇文法FILE* fp=fopen(&

21、quot;D:/rull.txt","r");if(fp=NULL)cout<<"打開文件失敗"<<endl;getchar();exit(0);/讀取文件string source=""char readchar;doreadchar=fgetc(fp);source+=readchar;while(readchar!=EOF);fclose(fp);/cout<<"-source流-"<<endl<<source<<endl;/檢

22、查/從source流中提取有效數(shù)據(jù)Vs=source3;Vn+=Vs;int i,j,k,l;string ps=""for(i=8;sourcei!=''i+) Vn+=sourcei;i+=4;for(;sourcei!=''i+) Vt+=sourcei;i+;while(sourcei!='')for(;sourcei!=' '&&sourcei!=''i+)ps+=sourcei;QRULL.push_back(ps);ps=""if(sourcei

23、=' ') i+;/拆分或符號string ps2=""int flag;for(i=0;i<QRULL.size();i+)flag=0;for(j=0;j<QRULLi.length();j+)if(QRULLij='|')flag=1;break;if(flag=0) continue;ps2+=QRULLi0;ps2+="->"for(j=0;QRULLij!='|'j+) ps+=QRULLij;for(j+;j<QRULLi.length();j+) ps2+=QRULL

24、ij;QRULLi=ps;QRULL.push_back(ps2);ps=""ps2=""cout<<"-有效四元產(chǎn)生式表-"<<endl;/檢查for(i=0;i<QRULL.size();i+)/檢查cout<<QRULLi<<' '/檢查cout<<endl;/檢查/從四元產(chǎn)生式轉(zhuǎn)化為普通產(chǎn)生式ps=""for(i=0;i<QRULL.size();i+)k=0;ps=""for(j=0;j<QR

25、ULLi.size();j+)if(QRULLij!='') ps+=QRULLij;else j+=2;RULL.push_back(ps);cout<<"-有效普通產(chǎn)生式表-"<<endl;/檢查for(i=0;i<RULL.size();i+)/檢查cout<<RULLi<<' '/檢查cout<<endl;/檢查/檢測直接左遞歸flag=0;for(i=0;i<RULL.size();i+)if(RULLi0=RULLi3) flag=1;if(flag=1)sy

26、stem("cls");system("color CF");cout<<"檢測到直接左遞歸文法,系統(tǒng)已停止運(yùn)行,請改正產(chǎn)生式。"<<endl;getchar();exit(0);/產(chǎn)生SELECT表Vt+='#'MAXITERATE=RULL.size()*RULL.size();vector<string> SELECT;SELECT=Select();cout<<"-SELECT集-"<<endl<<"SELEC

27、T"<<endl;/檢查for(i=0;i<SELECT.size();i+)/檢查cout<<SELECTi<<endl;/檢查SelectTable=new int*Vn.size();int* intp;for(i=0;i<Vn.size();i+)intp=new intVt.size();SelectTablei=intp;for(i=0;i<Vn.size();i+)for(j=0;j<Vt.size();j+) SelectTableij=-1;for(k=0;k<SELECT.size();k+)for

28、(l=2;l<SELECTk.length();l+)i=inVn(SELECTk0);j=inVt(SELECTkl);SelectTableij=k;cout<<"-SelectTable-"<<endl<<" "/檢測for(i=0;i<Vt.size();i+) cout<<Vti<<' '/檢測cout<<endl;/檢測for(i=0;i<Vn.size();i+)/檢測cout<<Vni<<' '

29、/檢測for(j=0;j<Vt.size();j+) cout<<SelectTableij<<' '/檢測cout<<endl;/檢測/進(jìn)行選擇集相交檢測if(check()=0)system("cls");system("color CF");cout<<"選擇集相交,該文法不是LL1文法,請修改產(chǎn)生式"<<endl;getchar();exit(0);vector<string> Select()int i;vector<stri

30、ng> SELECT;string ps=""for(i=0;i<RULL.size();i+)ps=RULLi0;ps+=" "ps+=first(RULLi);SELECT.push_back(ps);/迭代器清零counter=0;return SELECT;string first(string rull)/cout<<"迭代次數(shù)"<<counter<<endl;/檢測counter+;if(counter>MAXITERATE)system("cls"

31、);system("color CF");cout<<"生成選擇集時迭代次數(shù)過高,疑似出現(xiàn)遞歸死循環(huán),系統(tǒng)已停止運(yùn)行,請檢查是否有語法錯誤"<<endl;cout<<"迭代次數(shù)上限暫設(shè)為產(chǎn)生式數(shù)量的平方。過多的迭代會損害設(shè)備,若沒有語法錯誤,請簡化語法樹"<<endl;getchar();exit(0);int i,j;string pp;string res=""if(inVt(rull3)>=0) res=rull3;else if(inVn(rull3)&

32、gt;=0) for(i=0;i<RULL.size();i+)pp=rull;if(RULLi0=pp3)pp=pp0;pp+="->"for(j=3;j<RULLi.size();j+) pp+=RULLij;for(j=4;j<rull.size();j+) pp+=rullj;res+=first(pp);else if(rull3='0') res+=follow(rull);elsesystem("cls");system("color CF");cout<<"

33、產(chǎn)生式關(guān)鍵位置檢測到非法字符,系統(tǒng)已停止運(yùn)行。"<<endl;getchar();exit(0);return res;string follow(string rull)/cout<<"迭代次數(shù)"<<counter<<endl;/檢測counter+;if(counter>MAXITERATE)system("cls");system("color CF");cout<<"生成選擇集時迭代次數(shù)過高,疑似出現(xiàn)遞歸死循環(huán),系統(tǒng)已終止運(yùn)行,請檢查是否有語

34、法錯誤"<<endl;cout<<"迭代次數(shù)上限暫設(shè)為產(chǎn)生式數(shù)量的平方。過多的迭代會損害設(shè)備,若沒有語法錯誤,請簡化語法樹"<<endl;getchar();exit(0);vector<string> p;string res;string pp=""string t=""int i,site,j;if(rull0=Vs) res+='#'for(i=0;i<RULL.size();i+)pp=""for(j=3;j<RULLi

35、.length();j+) pp+=RULLij;pp+='0'site=pp.find(rull0,0);while(site<pp.size()site=pp.find(rull0,site);if(site=-1) break;t=RULLi0;t+="->"for(j=site+1;j<pp.length();j+) t+=ppj;pp=t;if(pp3='0'&&pp0=rull0) continue;p.push_back(pp);site+;for(i=0;i<p.size();i+) r

36、es+=first(pi);return res;3.2.2遞歸下降子程序的設(shè)計l 設(shè)計原理如下: 對每一個非終結(jié)符,構(gòu)造一個子程序,用以識別該非終結(jié)符所定義的符號串。每個子程序以產(chǎn)生式左部非終結(jié)符命名,以產(chǎn)生式右部構(gòu)造子程序內(nèi)容。l 構(gòu)造算法如下: 擴(kuò)展文法:增設(shè)一個產(chǎn)生式,作為主程序:Z->Z , 入出口約定: 子程序入口時,其首符號已經(jīng)讀來!子程序出口時,其后繼符應(yīng)該讀來! 子程序內(nèi)容設(shè)計:遇終結(jié)符,判定之 ,確認(rèn)后讀下一單詞;遇非終結(jié)符,調(diào)用之,返回后不讀下一單詞; 遇空串(e) ,直接出口; 入口出口NEXT(w)F 2Fyn入口出口NEXT(w)T 1Tynl 程序流程圖如下

37、:開始結(jié)束 #ENEXT(w)err0yn 3.3中間語言生成器算法 中間語言生成主要是對四元式序列的設(shè)計,其算法設(shè)計如下: 1)賦值語句的四元式設(shè)計 設(shè)有賦值語句:v = E ,則有v = E =>quat(E),q(:= res(E) _ v ) 算法實(shí)現(xiàn)如下: void Z(int end) /賦值語句四元式生成int i;string str;if(VTOKENtokenp+3.compare("<PT,21>")!=0)tokenp+=2; LL1(end-1);str=VTOKENtokenp+1;str+=SEM.top();SEM.pop(

38、);str+="<0,0>"str+=VTOKENtokenp;QT.push_back(str);elsestr=VTOKENtokenp+1;str+=VTOKENtokenp+2;str+="<0,0>"str+=VTOKENtokenp;QT.push_back(str);cout<<"驗(yàn)證賦值語句并產(chǎn)生四元式"<<endl;2) 條件語句的四元式設(shè)計文法:S -> if(E)S1 else S2 quat(E)q1(if res(E)_ _ )quat(S1)q2(el

39、_ _ _ )quat(S2)q3(ie _ _ _ )語義結(jié)構(gòu) : 四元式結(jié)構(gòu): E執(zhí)行S1執(zhí)行S2可選 falsetrue入口出口算法實(shí)現(xiàn)如下:void V(int end) /if語句四元式生成string str;int p,f=0;tokenp+;if(VTOKENpare("<PT,0>")=0) f+=1;p=tokenp+1;else cout<<"源代碼錯誤-ERRO:02/if 當(dāng)前TOKEN:"<<tokenp<<endl; getchar();exit(0); d

40、o if(VTOKENpare("<PT,0>")=0)f+=1; else if(VTOKENpare("<PT,1>")=0)f-=1; p+; while(f!=0); if(p-1-tokenp)=1) cout<<"源代碼錯誤-ERRO:02/if括號 當(dāng)前TOKEN:"<<tokenp<<endl; getchar();exit(0); if(p-1-tokenp)=2) string tt; tt=VTOKENtokenp+1; str=&q

41、uot;<KT,3>" str+=tt; str+="<0,0>" str+="<0,0>"QT.push_back(str);tokenp+=3; else tokenp+; LL1(p-2); tokenp=p; str="<KT,3>" str+=SEM.top(); SEM.pop(); str+="<0,0>" str+="<0,0>" QT.push_back(str); C(end);cout<

42、<"驗(yàn)證if語句并產(chǎn)生四元式"<<endl;void N(int end) /else語句四元式生成 string str;str="<KT,1>"str+="<0,0>"str+="<0,0>"str+="<0,0>"QT.push_back(str);tokenp+;C(end);cout<<"驗(yàn)證else語句并產(chǎn)生四元式"<<endl;3)循環(huán)語句的四元式設(shè)計文法:S ->

43、while(E)S 語義結(jié)構(gòu): 四元式結(jié)構(gòu):q2(do res(E)_ _ )quat(S)q3(we _ _ _ )q1(wh _ _ _ )quat(E) E 執(zhí)行 Sfalsetrue入口 出口 算法實(shí)現(xiàn)如下:void W(int end) /循環(huán)語句四元式生成string str; int p,f=0;str="<KT,7>"str+="<0,0>"str+="<0,0>"str+="<0,0>"QT.push_back(str);tokenp+;p=toke

44、np;do if(VTOKENpare("<PT,0>")=0)f+=1; else if(VTOKENpare("<PT,1>")=0)f-=1; p+; while(f!=0); if(p-1-tokenp)=1) cout<<"源代碼錯誤-ERRO:02/while括號當(dāng)前TOKEN:"<<tokenp<<endl; getchar();exit(0); if(p-1-tokenp)=2) string tt; tt=VTOKENtokenp+1;

45、str="<KT,8>" str+=tt; str+="<0,0>" str+="<0,0>"QT.push_back(str);tokenp+=3; elsetokenp+;LL1(p-2);str="<KT,8>"str+=SEM.top();SEM.pop();str+="<0,0>"str+="<0,0>"QT.push_back(str); tokenp=p;C(end);str="&

46、lt;KT,10>"str+="<0,0>"str+="<0,0>"str+="<0,0>"QT.push_back(str);cout<<"驗(yàn)證了循環(huán)語句并產(chǎn)生四元式"<<endl;3.4處理復(fù)合表達(dá)式的算法1) 表達(dá)式四元式設(shè)計文法:Vs E; Vn XTYFMNQSAB; Vt jcibpk(); E->TX X->jTGX|0 T->FY Y->cFGY|0 F->MN N->bMGN|0 M-&

47、gt;SQ Q->pSGQ|0 S->AB B->kAGB|0 A->iP|(E);四元式結(jié)構(gòu):q:( o1 o2 t )/*算符,對象1,對象2,結(jié)果*/算法實(shí)現(xiàn)如下:void GEQ(string a)/運(yùn)算符a,計數(shù)器qtpchar p10;ele num;="t"num.val="0"int i=0;string str;string left;/左操作數(shù)string right;/右操作數(shù)string t;if(pare("<PT,5>")=0|pare("<

48、;PT,22>")=0)SEM.push("<0,0>"); right=SEM.top();SEM.pop();left=SEM.top();SEM.pop();if(left1='C')str=translate(left);for(i=0;i<sizeof(str);i+)if(stri='.')ITf.push_back(num);t+="<ITf,"itoa(ITf.size()-1,p,10);t+=p;t+=">"break;else cont

49、inue;ITi.push_back(num);t+="<ITi,"itoa(ITi.size()-1,p,10);t+=p;t+=">"elseint flag=0;str=translate(left);for(i=0;i<ITi.size();i+)if(pare(IT)=0)flag=1;break;else continue;for(i=0;i<ITf.size()&&flag=0;i+)if(pare(IT)=0)flag=2;break;else continue;for(

50、i=0;i<ITc.size()&&flag=0;i+)if(pare(IT)=0)flag=3;break;else continue;switch(flag)case 0:cout<<"使用了未聲明的變量-ERRO:02 當(dāng)前TOKEN:"<<tokenp<<endl;exit(0);/未聲明的變量case 1:ITi.push_back(num);t+="<ITi,"itoa(ITi.size()-1,p,10);t+=p;t+=">"break

51、;case 2:ITf.push_back(num);t+="<ITf,"itoa(ITf.size()-1,p,10);t+=p;t+=">"break;case 3:ITc.push_back(num);t+="<ITc,"itoa(ITc.size()-1,p,10);t+=p;t+=">"break;if(right1='I'&&right3=',')int flag=0;str=translate(right);for(i=0;i&l

52、t;ITi.size();i+)if(pare(IT)=0)flag=1;break;else continue;for(i=0;i<ITf.size()&&flag=0;i+)if(pare(IT)=0)flag=2;break;else continue;for(i=0;i<ITc.size()&&flag=0;i+)if(pare(IT)=0)flag=3;break;else continue;if(flag=0)cout<<"使用了未聲明的變量-ERRO:02 當(dāng)前TOKEN:"<<tokenp<<endl;exit(0);a+=left;a+=right;a+=t;QT.push_back(a);SEM.push(t);2) 帶語義動作的LL(1)自動機(jī)開始 初始化 #入棧,開始符號E入棧 N N/P? P read(w)執(zhí)行棧操作(SYN(top),w)查分析表結(jié)束空?OK? y n y err算法實(shí)現(xiàn)如下:(1) 將token翻譯成非終結(jié)符if(to

溫馨提示

  • 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論