編譯原理實驗2-語法分析(C++代碼實現(xiàn))_第1頁
編譯原理實驗2-語法分析(C++代碼實現(xiàn))_第2頁
編譯原理實驗2-語法分析(C++代碼實現(xiàn))_第3頁
編譯原理實驗2-語法分析(C++代碼實現(xiàn))_第4頁
編譯原理實驗2-語法分析(C++代碼實現(xiàn))_第5頁
已閱讀5頁,還剩4頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

編譯原理實驗2——語法分析(C++代碼實現(xiàn))?、實驗?的語法分析是編譯程序中的核?部分。本實驗通過設計?個典型的?頂向下語法分析程序——LL(1)語法分析程序,進?步理解并掌握語法分析的原理和實現(xiàn)技術。?、實驗原理語法分析的主要任務是“組詞成句”,將詞法分析給出的單詞序列按語法規(guī)則構成更?的語法單位,如“程序、語句、表達式”等;或者說,語法分析的作?是?來判斷給定輸?串是否為合乎?法的句?。按照?成語法樹的?向不同,常?的語法分析?法有兩類:?頂向下分析和?底向上分析。?頂向下分析也稱?向?標的分析?法,也就是從?法的開始符出發(fā),試圖推導出與輸?單詞串相匹配的句?。?底向上分析也稱移進-歸約分析?法,從輸?單詞串開始,試圖歸約到?法的開始符。預測分析法(LL(1)?法)的基本思想是:從?法開始符S出發(fā),從左到右掃描源程序,每次通過向前查看1個字符,選擇合適的產(chǎn)?式,?成句?的最左推導。三、實驗步驟與要求1、復習教材第4章,進?步理解LL(1)?法的原理和實現(xiàn)技術。根據(jù)預測分析程序的框圖(教材P94-圖5.11),編寫?個語法分析程序??筛鶕?jù)??的能?選擇以下三項(由易到難)之?作為分析算法的輸?:(1)根據(jù)?法,??構造分析表M,直接輸?表M。(2)輸??法的FIRST集和FOLLOW集,由程序?動?成該?法的預測分析表M。(3)輸??法,由程序?動?成該?法的預測分析表M。2、程序具有通?性,即所編制的LL(1)語法分析程序能夠適?于不同?法以及各種輸?單詞串。3、有運?實例。對于輸?的?個?法和?個單詞串,語法分析程序應能正確地判斷此單詞串是否為該?法的句?,并要求輸出分析過程。4、設計合理的數(shù)據(jù)結構,特別是?法、預測分析表、分析棧等的存儲結構。四、實驗代碼//#include"pch.h"#include<iostream>#include<stdio.h>#include<string.h>#include<stdlib.h>#include<stack>usingnamespacestd;voidGramF();//分解產(chǎn)?式程序voidGramIn();//?法輸?程序voidWordIn();//?字輸?程序boolIs(charx,chara[],intn);//是否在集合中voidGetFirst(chara);//first集求解程序voidADD(string&a,string&b);//集合相加程序集合voidADDfollow(string&a,string&b);//(follow)相加程序intBack(chara);//根據(jù)字母返回下標程序voidGetFollow(chara);//follow集求解程序boolIsChar(chara,stringb);//判斷?個字符是否在?個集合中的程序voidFAtable();//預測分析表構建程序voidGAnalysis();//?法分析程序voidclearF();//凈化程序voidcc();//i+()*ABCDEA->BCC->+BC|@B->DEE->*DE|@D->(A)|iinttable[100][100]={0};//預測表charVt[100]={""};//終結符charVn[100]={""};//?終結符stringGenerative[100]={""};//?法產(chǎn)?式存儲stringGenerativeNew[100]={""};//?法產(chǎn)?式分解后的存儲stringfirst[100]={""};//first集合stringfollow[100]={""};//follow集合charword[100]={""};//待測試的?字intVtNum=0;//終結符號的個數(shù)intVtNum=0;//終結符號的個數(shù)intVnNum=0;//?終結符號的個數(shù)intGenNum=0;//?法產(chǎn)?式個數(shù)intGenNumNew=0;//?法產(chǎn)?式分解后的個數(shù)stack<char>st;//預測分析棧voidcc(){inti,j,k,q,p;for(i=0;i<VnNum;i++){j=0;while(first[i][j]!='\0'){k=j+1;while(first[i][k]!='\0'){if(first[i][j]==first[i][k])first[i][k]='';k++;}j++;}q=0;while(first[i][q]!='\0'){if(first[i][q]!=''){break;}else{p=q+1;while(first[i][p]!=''){if(first[i][p]=='\0')break;else{first[i][q]=first[i][p];first[i][p]='';}}}q++;}q=0;while(first[i][q]!='\0'){if(first[i][q]=='')first[i][q]='\0';q++;}}}/*************************/分解?法產(chǎn)?式程序voidGramF(){intj,z=0,x;for(inti=0;i<GenNum;i++){x=0;while(1){charch1=Generative[i][x];if(ch1=='\0'||ch1=='|')break;GenerativeNew[z]+=Generative[i][x];x++;}z++;j=0;while(Generative[i][j]!='\0'){if(Generative[i][j]=='|'){j++;for(x=0;x<3;x++){GenerativeNew[z]+=Generative[i][x];}while(1){while(1){charch2=Generative[i][j];if(ch2=='\0'||ch2=='|')break;GenerativeNew[z]+=Generative[i][j];j++;}z++;}else{j++;}}}GenNumNew=z;}/************?法輸?程序*************/voidGramIn(){inti=0;printf("請輸?終結符號:\n");scanf_s("%c",Vt+i,1);while(*(Vt+i)!='\n'){i++;scanf_s("%c",Vt+i,1);}Vt[i]='#';i++;VtNum=i;//輸?結束存儲終結符號個數(shù)i=0;//i初始化值準備輸??終結符號printf("請輸??終結符號:\n");scanf_s("%c",Vn+i,1);while(*(Vn+i)!='\n'){i++;scanf_s("%c",Vn+i,1);}VnNum=i;//輸?結束存儲?終結符號個數(shù)i=0;//i初始化值準備輸??法產(chǎn)?式printf("請輸??法產(chǎn)?式:\n");charch;while(cin>>Generative[i]){i++;if((ch=getchar())=='\n')break;}GenNum=i;//輸?結束存儲?法產(chǎn)?式個數(shù)}/************?字輸?程序*************/voidWordIn(){printf("請輸?您需要測試的?字:\n");inti=0;//getchar();scanf_s("%c",word+i);while(*(word+i)!='\n'){i++;scanf_s("%c",word+i);}}/************是否在集合中*************/boolIs(charx,chara[],intn){for(inti=0;i<n;i++){if(a[i]==x)returntrue;}returnfalse;returnfalse;}/************first集求解程序*************/voidGetFirst(chara){intk=0;for(inti=0;i<GenNumNew;i++){if(GenerativeNew[i][0]!=a)continue;if(Is(GenerativeNew[i][3],Vt,VtNum)){//如果該?終結符產(chǎn)?式右部第?個字符是終結符,號則直接將其計?左部?終結符的FIRST集first[Back(GenerativeNew[i][0])]+=GenerativeNew[i][3];}elseif(Is(GenerativeNew[i][3],Vn,VnNum)){//如果該?終結符號右部第?個字符是?終結符,號則對該右部第?個字符的FIRST進?求解,并將其加?左部字符的GetFirst(GenerativeNew[i][3]);FIRST集ADD(first[Back(GenerativeNew[i][0])],first[Back(GenerativeNew[i][3])]);}elseif(GenerativeNew[i][3]=='@'){//,FIRST如果該?終結符產(chǎn)?式是個空則將空加?左部字符的集intj=0;while(first[Back(GenerativeNew[i][0])][j]!='\0'){if(first[Back(GenerativeNew[i][0])][j]=='@'){k=1;break;}j++;}if(!k)first[Back(GenerativeNew[i][0])]+='@';}}}/************follow*************/集清除重復元素程序voidclearF(){inti,j,k,q,p;//follow集下?是清除for(i=0;i<VnNum;i++){j=0;while(follow[i][j]!='\0'){k=j+1;while(follow[i][k]!='\0'){if(follow[i][j]==follow[i][k])follow[i][k]='';k++;}j++;}q=0;p=0;while(follow[i][q]!='\0'){if(follow[i][q]!=''){break;}else{p=q+1;while(follow[i][p]!=''){if(follow[i][p]=='\0')break;else{follow[i][q]=follow[i][p];follow[i][p]='';}}}q++;}}q=0;while(follow[i][q]!='\0'){if(follow[i][q]=='')follow[i][q]='\0';q++;}}}/************集合相加程序*************/voidADD(string&a,string&b){inti=0,zk=1,j=0;while(b[j]!='\0'){i=0;zk=1;while(a[i]!='\0'){if(b[j]==a[i]||b[j]=='@'){zk=-1;break;}i++;}if(zk==1)a+=b[j];j++;}}/************集合(follow)相加程序*************/voidADDfollow(string&a,string&b){inti=0,zk=1,j=0;while(b[j]!='\0'){i=0;zk=1;while(a[i]!='\0'){if(b[j]==a[i]){zk=-1;break;}i++;}if(zk==1)a+=b[j];j++;}}/************follow集求解程序*************/voidGetFollow(chara){inti=Back(a),j;//if(i==0||i==1||i==2||i==3){//如果待求解字符是開始字符,則把'#'加?其//if(IsChar(a,follow[Back(a)]))follow[Back(a)]+='#';FOLLOW集for(j=0;j<GenNumNew;j++){if(GenerativeNew[j][3]==a&&GenerativeNew[j][4]!='\0'){//如果是A->Bbif(Is(GenerativeNew[j][4],Vt,VtNum)){//如果b是終結符號,直接加?follow(B)if(IsChar(GenerativeNew[j][4],follow[Back(a)]))//判斷b是否在follow(B)中continue;elsefollow[Back(a)]+=GenerativeNew[j][4];}elseif(Is(GenerativeNew[j][4],Vn,VnNum)){//如果b是?終結符號,需要判斷if(IsChar('@',first[Back(GenerativeNew[j][4])])){//如果b可以推出空'@',則需要將follow(A)加?follow(B)GetFollow(GenerativeNew[j][0]);ADDfollow(follow[Back(a)],follow[Back(GenerativeNew[j][0])]);}ADD(follow[Back(a)],first[Back(GenerativeNew[j][4])]);ADD(follow[Back(a)],first[Back(GenerativeNew[j][4])]);}}elseif(GenerativeNew[j][4]==a&&GenerativeNew[j][5]!='\0'){//如果是A->aBbif(Is(GenerativeNew[j][5],Vt,VtNum)){//如果b是終結符號,直接加?follow(B)if(IsChar(GenerativeNew[j][5],follow[Back(a)]))//判斷b是否在follow(B)中continue;elsefollow[Back(a)]+=GenerativeNew[j][5];}elseif(Is(GenerativeNew[j][5],Vn,VnNum)){//如果b是?終結符號,需進?判斷if(IsChar('@',first[Back(GenerativeNew[j][5])])){//如果b可以推出空'@',則需要將follow(A)加?follow(B)GetFollow(GenerativeNew[j][0]);ADDfollow(follow[Back(a)],follow[Back(GenerativeNew[j][0])]);}ADD(follow[Back(a)],first[Back(GenerativeNew[j][5])]);}}elseif(GenerativeNew[j][4]==a&&GenerativeNew[j][5]=='\0'){//如果是A->aBGetFollow(GenerativeNew[j][0]);//直接將follow(A)加?follow(B)ADDfollow(follow[Back(a)],follow[Back(GenerativeNew[j][0])]);}}//}}/************判斷?個字符是否在?個集合中的程序*************/boolIsChar(chara,stringb){inti=0;while(b[i]!='\0'){if(a==b[i])returntrue;i++;}returnfalse;}/*************************/預測分析表構建程序voidFAtable(){inti,j;for(i=0;i<VtNum;i++){for(j=0;j<GenNumNew;j++){if(Vt[i]==GenerativeNew[j][3])//如果終結符中則將A->a放?table[A,Vt[i]]Vt[i]A->afirst(a),在的中table[Back(GenerativeNew[j][0])][i]=j;elseif(Is(GenerativeNew[j][3],Vn,VnNum)){if(IsChar(Vt[i],first[Back(GenerativeNew[j][3])])){table[Back(GenerativeNew[j][0])][i]=j;}}elseif(GenerativeNew[j][3]=='@'){//如果當前的產(chǎn)?式是:A->a且,a='@',則判斷當前的Vt[i]是否在if(IsChar(Vt[i],follow[Back(GenerativeNew[j][0])])){table[Back(GenerativeNew[j][0])][i]=j;}}}}}/************根據(jù)字母返回終結符下標程序*************/intBBack(chara){for(inti=0;i<VtNum;i++){if(a==Vt[i])returni;}return-1;}/************根據(jù)字母返回?終結符下標程序*************//************根據(jù)字母返回?終結符下標程序*************/intBack(chara){for(inti=0;i<VnNum;i++){if(a==Vn[i])returni;}return-1;}/************?法分析程序*************/voidGAnalysis(){inti=0,x,y,k,error=0,n=1;chara;stringchan="";st.push('#');st.push(Vn[0]);a=st.top();while(!(a==word[i]&&a=='#')){if(Is(st.top(),Vn,VnNum)){x=Back(st.top());y=BBack(word[i]);k=table[x][y];//獲得產(chǎn)?式if(k==-1){error++;cout<<"步驟["<<n<<"]:識別錯誤!跳過"<<word[i]<<";\n";n++;i++;break;}else{chan=GenerativeNew[k];k=0;st.pop();while(chan[k]!='\0'){k++;}k--;if(chan[k]!='@'){while(chan[k]!='>'){st.push(chan[k]);k--;}//i++;cout<<"步驟["<<n<<"]:?"<<chan<<"的右部分逆序?棧已經(jīng)完成;\n";n++;}else{cout<<"步驟["<<n<<"]:?"<<chan<<";\n";n++;//i++;}}}elseif(Is(st.top(),Vt,VtNum)){if(st.top()==word[i]){cout<<"步驟["<<n<<"]:匹配棧頂和當前符號"<<word[i]<<",成功;\n";st.pop();i++;n++;}else{cout<<"步驟["<<n<<"]:識別失?。。n";n++;break;}}a=st.top();a=st.top();}if(error){cout<<"步驟["<<n<<"]:識別錯誤??!錯誤跳過次數(shù):"<<error<<"\n";n++;}else{cout<<"步驟["<<n<<"]:識別成功!!\n";n++;}}voidChuShi(){for(inti=0;i<100;i++){for(intj=0;j<100;j++){table[i][j]=-1;}}}intmain(){usingstd::cout;cout.setf(std::ios::left);ChuShi();//初始化?維數(shù)組GramIn();//輸??終結、終結字符和?法產(chǎn)?式GramF();//?法產(chǎn)?式分析完畢inti,j;for(

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論