實驗詞法分析程序_第1頁
實驗詞法分析程序_第2頁
實驗詞法分析程序_第3頁
實驗詞法分析程序_第4頁
實驗詞法分析程序_第5頁
已閱讀5頁,還剩37頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、實驗1 詞法分析程序一、實驗目的與要求1. 復習正規(guī)文法、正規(guī)式、有限自動機之間的相互轉(zhuǎn)換的原理及技術(shù);2. 學會使用Visual C+等高級語言編程實現(xiàn)上述轉(zhuǎn)換,并能合理顯示結(jié)果;3. 以C+的一個真子集為案例,具體分析詞法分析程序的設計步驟、基本架構(gòu)及代碼編制,并通過一定實例驗證其可行性,以加深對詞法分析原理的理解;4. 通過本次實驗,使學生理解模塊化程序設計的思想,從而從全局角度領(lǐng)會一個完整軟件的設計精髓,為后續(xù)試驗的順利完成奠定堅實的基礎。二、實驗儀器及設備1. 微型電子計算機80臺2. 配置Windows 2000及以上版本操作系統(tǒng)3. 安裝Visual C+6.0/Visual C

2、#2000/Delphi6.0等以上版本的開發(fā)環(huán)境三、實驗內(nèi)容及步驟(一)正規(guī)文法與有限自動機的相互轉(zhuǎn)換1正規(guī)文法 Þ 有限自動機已知某正規(guī)文法GS如下:SaASbBSAaBAbABaSBbAB請編程實現(xiàn):(1) 將GS轉(zhuǎn)換為NFA;(2) 將上述得到的NFA確定化為DFA;(3) 再將DFA最簡化為MFA。2有限自動機 Þ 正規(guī)文法已知某有限自動機 NFA M=(Q,f,q0,Z)如下:狀態(tài)集:Q=1,2,3,4,5,6,7,8,9字母表:=a,b轉(zhuǎn)移函數(shù):f(1,a)=5f(1,)=2f(1,a)=4f(5,)=6f(2,b)=3f(4,)=7f(6,)=2f(6,b)

3、=9f(3,)=8f(8,a)=9f(7,b)=9初態(tài):q0=1終態(tài)集:Z=6,7,9請編程實現(xiàn):(1) 首先將此NFA確定化為DFA;(2) 再將得到的DFA最簡化為MFA;(3) 最后,將MFA轉(zhuǎn)化為正規(guī)文法(左線性或右線性均可)。(二)編程實現(xiàn)MiniC+的詞法分析這里的MiniC+為C+語言的一個真子集,其語法結(jié)構(gòu)與C+類似。基本組成如下:(1) 關(guān)鍵字有18個,分別為:void、int、char、bool、float、double、if、else、switch、case、default、break、continue、do、while、for、return以及struct等。(2) 標

4、識符:定義為“以字母或下劃線開頭,由字母、數(shù)字或下劃線組成的符號串?!保?) 常量:包括數(shù)字(暫時僅考慮無符號整數(shù))、字符串、字符常量等。(4) 分隔符:( ) . , : ; ? # 等。(5) 運算符:=、=、>、>=、<、<=、!、!=、&&、&=、|、|=、+、+、- 、=、->、/、/=、%、%=等。要求同學們完成下述工作:1 基于上述描述,根據(jù)你的理解,嘗試寫出該MiniC+的文法GS;2 再根據(jù)你所寫的文法GS,繪制出MiniC+的NFA狀態(tài)圖,并進而推導出最簡化的MFA;3 根據(jù)你推導出的MFA,編寫MiniC+的詞法分析程

5、序,并用下面的源代碼測試你所設計的程序。/測試函數(shù)調(diào)用,求N!int f(int a)if(a=1)a=1;else a=a*f(a-1);return a;void main()int i,a;cout<<"please input n =:"<<endl;cin>>i;a=f(i);cout<<"n! ="<<a;將程序輸出的單詞流與理論分析的結(jié)果比較分析,若有差錯,請找出原因,并進一步修改你的程序,直至得到正確的結(jié)果。四、思考題1. 將實驗內(nèi)容(一)中的文法GS轉(zhuǎn)化為正規(guī)式;2. 將實驗內(nèi)

6、容(一)中的有限自動機M轉(zhuǎn)化為正規(guī)式。五、實驗報告1. 實驗報告撰寫在統(tǒng)一配發(fā)的紙質(zhì)報告冊上,下次上課時交給老師。2. 實驗報告格式如下。實驗1 詞法分析程序一、實驗目的與要求二、實驗儀器及設備三、實驗內(nèi)容1根據(jù)指導書要求,按順序解答;2要求有結(jié)果,尤其是程序顯示結(jié)果;3不需要附上源代碼。四、思考題五、實驗小結(jié)闡述實驗中碰到的問題、解決的方法或技術(shù)、得到的結(jié)論、體會感觸等。六、參考代碼(一)CGrammar類1頭文件Grammar.h#pragma warning(disable:4786)/屏蔽“由于string和vector等STL模版產(chǎn)生很長的標識符而引起的警告信息”#include&l

7、t;iostream>#include<iomanip>#include<string>#include<fstream>#include<vector>/使用vector容器#include <sstream>using namespace std;struct CreateFormula/ 產(chǎn)生式string LeftPart;/ 左部string RightPart;/ 右部;class CGrammarpublic:CGrammar();CGrammar();/外部操作函數(shù):void SetGrammar(char *F

8、ilename);/ 根據(jù)文件內(nèi)容設置文法產(chǎn)生式void DelDirectLeftRecursion(int i);/ 消除“直接”左遞歸bool DelIndirectLeftRecursion();/ 消除“間接”左遞歸bool HavingRedundance();/ 含有無用產(chǎn)生式void MiniGrammar();/ 文法化簡void DisplayGrammar();/ 顯示文法void DisplayGrammar(char *Filename);/ 將文法產(chǎn)生式保存在txt文件/返回文法屬性的函數(shù):int GetGrammarType();/ 返回文法類型bool GetH

9、avingLeftRecursion();/ 是否存在左遞歸vector<string>GetVN();/ 返回非終結(jié)符vector<string>GetVT();/ 返回終結(jié)符vector<CreateFormula>GetCF();/ 返回產(chǎn)生式數(shù)據(jù)string GetStartSign();/ 返回開始符號public:/基本函數(shù):bool FindSign(string str,vector<string>&VnVt);/ 查找某符號串str是否屬于VnVtvector<string> GetSingleSign(st

10、ring str);/分解字符串為單個符號(包括形式為E'的符號)private:void CountVn_and_Vt();/ 求非終結(jié)符和終結(jié)符集bool EnableDelLeftRecursion();/ 能否刪除左遞歸void ExistDirectLeftRecursion();/ 含有“直接”左遞歸void ExistIndirectLeftRecursion();/ 含有“間接”左遞歸bool IS_0_Grammar();/ 識別0型文法bool IS_1_Grammar();/ 識別1型文法bool IS_2_Grammar();/ 識別2型文法bool IS_3_

11、Grammar();/ 識別3型文法void GrammarType();/ 判斷文法類型string CreateNewVn(string vn);/ 構(gòu)造新的非終結(jié)符protected:/ 文法結(jié)構(gòu)vector<string>NoEndSign;/ 非終結(jié)符集vector<string>EndSign;/ 終結(jié)符集vector<CreateFormula>GR_Array;/ 產(chǎn)生式集合string StartSign;/ 開始符號int GrammarTypeNum;/ 文法類型號碼private:int GR_Number;/ 產(chǎn)生式的總數(shù)bool

12、IsDirectLeftRecursion;/ 含有直接左遞歸的標識bool IsIndirectLeftRecursion;/ 含有間接左遞歸的標識;2實現(xiàn)文件Grammar.cpp#include "Grammar.h"#define KONG ""CGrammar:CGrammar()GR_Array.reserve(1000);/很重要,預先劃分一塊內(nèi)存給vector使用GrammarTypeNum=-1;IsDirectLeftRecursion=false;IsIndirectLeftRecursion=false;CGrammar:CGra

13、mmar()/從txt文件中獲取文法的產(chǎn)生式集合:/規(guī)則:不用簡寫;用“”連接;用“”表示空串;每行一條產(chǎn)生式。void CGrammar:SetGrammar(char *Filename)ifstream fin(Filename,ios:in);char line1024=0;int pos;CreateFormula temp;if(!GR_Array.empty()GR_Array.clear();/清空 while(fin.getline(line, sizeof(line)/下面的一段代碼用于刪除產(chǎn)生式中的所有空格:char templine200=""int

14、 i=0,j=0;while(linei)if(linei!=' '&&linei!=''&&linei!='')templinej=linei;j+;i+;templinej+1='0'/操作結(jié)束string s(templine);if(pos=s.find("")>=100)continue;temp.LeftPart=s.substr(0,pos);temp.RightPart =s.substr(pos+2,s.length()-pos);/""

15、;是漢字符號,所以“+2”GR_Array.push_back(temp);GR_Number=GR_Array.size();fin.clear();fin.close();/初始化操作:CountVn_and_Vt();/ 求非終結(jié)符集、終結(jié)符集GrammarType();/ 判斷文法的分類類型ExistDirectLeftRecursion();/ 判斷是否存在直接左遞歸ExistIndirectLeftRecursion();/ 判斷是否存在間接左遞歸/ 將文法產(chǎn)生式保存在txt文件void CGrammar:DisplayGrammar(char *Filename)ofstream

16、 fout(Filename,ios:out);for(int i=0;i<GR_Array.size();i+) fout<<setw(2)<<left<<GR_Arrayi.LeftPart<<""<<left<<GR_Arrayi.RightPart<<endl; fout.clear();fout.close();/ 查找某符號串str是否屬于某個容器VnVtbool CGrammar:FindSign(string str,vector<string>&V

17、nVt)for(int i=0;i<VnVt.size();i+) if(!(VnVpare(str)return true;return false;/求非終結(jié)符集Vn、終結(jié)符集Vtvoid CGrammar:CountVn_and_Vt()if(!NoEndSign.empty()NoEndSign.clear();if(!EndSign.empty()EndSign.clear(); for(int i=0;i<GR_Array.size();i+) /觀察產(chǎn)生式的左部vector<string>strtemp=GetSingleSign(GR_Arr

18、ayi.LeftPart);/分解左部為單個符號for(int j=0;j<strtemp.size();j+)string tempvn=strtempj;if(tempvn0>='A'&&tempvn0<='Z')/若為大寫字母則是非終結(jié)符if(!FindSign(tempvn,NoEndSign)/若是新的非終結(jié)符,則添加進去NoEndSign.push_back(tempvn);else /否則,則為終結(jié)符if(!FindSign(tempvn,EndSign)/若是新的終結(jié)符,則添加進去EndSign.push_bac

19、k(tempvn);/觀察產(chǎn)生式的右部if(GR_Arrayi.RightPpare("")/若不是X形式,則/分解右部為單個符號vector<string>strtemp1=GetSingleSign(GR_Arrayi.RightPart);for(int k=0;k<strtemp1.size();k+)string tempvt=strtemp1k;if(!(tempvt0>='A'&&tempvt0<='Z')/若不是大寫字母,則是終結(jié)符if(!FindSign(tempvt,EndSi

20、gn)/若是新的終結(jié)符,則添加進去EndSign.push_back(tempvt);else /否則,則為非終結(jié)符if(!FindSign(tempvt,NoEndSign)/若是新的終結(jié)符,則添加進去NoEndSign.push_back(tempvt);if(!NoEndSign.empty()StartSign=NoEndSign0;/ 文法開始符號默認為遇到的第一個非終結(jié)符/識別0型文法(所有產(chǎn)生式的左部含有非終結(jié)符):bool CGrammar:IS_0_Grammar()int CapitalNumInLeftPart;/某產(chǎn)生式左部的非終結(jié)符的數(shù)目,即大寫字母數(shù)int coun

21、t=0;for(int i=0;i<GR_Array.size();i+)CapitalNumInLeftPart=0;for(int j=0;j<GR_Arrayi.LeftPart.length();j+) string temp3=GR_Arrayi.LeftPart.substr(j,1);if(FindSign(temp3,NoEndSign)CapitalNumInLeftPart+;if(CapitalNumInLeftPart<=0)return false;/表示當前產(chǎn)生式的左部沒有非終結(jié)符,則直接終止return true;/是 0 型文法/識別1型文法(

22、即上下文有關(guān)文法,所有產(chǎn)生式的左部長度<=右部長度):bool CGrammar:IS_1_Grammar()for(int i=0;i<GR_Array.size();i+) if(GR_Arrayi.LeftPart.length()>GR_Arrayi.RightPart.length() /若左部大于右部,return false;return true;/識別2型文法(即上下文無關(guān)文法:左部長度=1,且左部為非終結(jié)符Vn)bool CGrammar:IS_2_Grammar()for(int i=0;i<GR_Array.size();i+)if(GR_Arr

23、ayi.LeftPart.length()!=1)/若左部長度不為1return false;string temp4=GR_Arrayi.LeftPart.substr(0,1);if(!FindSign(temp4,NoEndSign)return false;return true;/識別3型文法(即正規(guī)文法,分為右線性、左線性)bool CGrammar:IS_3_Grammar()int Flag1=0,Flag2=0;/分別代表右線性AaB、左線性ABa的個數(shù)for(int i=0;i<GR_Array.size();i+)if(GR_Arrayi.RightPart.len

24、gth()=1)/右部字符個數(shù)等于1,string temp1=GR_Arrayi.RightPart.substr(0,1);/取右部字符if(!FindSign(temp1,NoEndSign)&&!FindSign(temp1,EndSign)/ 若右部既不是終結(jié)符/,即不滿足Aa形式,也不是非終結(jié)符,既不滿足AB形式,則return false;else if(GR_Arrayi.RightPart.length()=2)/判斷是否右線性AaB或左線性ABa形式if(GR_Arrayi.RightPpare("")/若不是X形式,則string te

25、mp2=GR_Arrayi.RightPart.substr(0,1);string temp3=GR_Arrayi.RightPart.substr(1,1);if(FindSign(temp2,EndSign)/ 若右部首字符是終結(jié)符&&FindSign(temp3,NoEndSign)/ 次首字符為非終結(jié)符,即AaBFlag1+;else if(FindSign(temp2,NoEndSign)/ 若右部首字符是非終結(jié)符&&FindSign(temp3,EndSign)/ 次首字符為終結(jié)符,即ABaFlag2+;elsereturn false;else

26、return false;if(Flag1>0&&Flag2>0)/同時含有右線性、左線性return false;elsereturn true;/判斷文法的類型void CGrammar:GrammarType()GrammarTypeNum=-1;if(IS_0_Grammar()GrammarTypeNum=0;if(IS_1_Grammar()GrammarTypeNum=1;if(IS_2_Grammar()GrammarTypeNum=2;if(IS_3_Grammar()GrammarTypeNum=3;/ 判斷是否含有“直接”左遞歸void CGr

27、ammar:ExistDirectLeftRecursion()for(int i=0;i<GR_Array.size();i+)string temp1=GR_Arrayi.LeftPart.substr(0,1);if(FindSign(temp1,NoEndSign)&&/若左部首字符為指定非終結(jié)符NoEndSigni,GR_Arrayi.LeftPart0=GR_Arrayi.RightPart0)/ ,且存在直接左遞歸IsDirectLeftRecursion=true;return;IsDirectLeftRecursion=false;/ 判斷是否含有“間接

28、”左遞歸void CGrammar:ExistIndirectLeftRecursion()vector<CreateFormula>:iterator Iter1,Iter2;vector<CreateFormula>GR_ArrayTemp;/備份用:GR_ArrayTemp.reserve(1000);GR_ArrayTemp=GR_Array;/此處僅是判斷是否存在左遞歸,/所有不能對原產(chǎn)生式進行破壞性操作,而只能對備份數(shù)據(jù)操作。for(int i=0;i<NoEndSign.size();i+)for(int j=0;j<i;j+)for(Iter

29、1=GR_ArrayTemp.begin();Iter1!=GR_ArrayTemp.end();Iter1+)string temp1=(*Iter1).LeftPart.substr(0,1);string temp2=(*Iter1).RightPart.substr(0,1);if(!pare(NoEndSigni)/左部首字符為Pi,&&!pare(NoEndSignj)/右部首字符為Pj,即形如PiPj/注:這里,是終結(jié)符,i、j是下標。/ 尋找所有形為:Pj.的產(chǎn)生式:for(Iter2=GR_ArrayTemp.begin();Iter2!=GR_ArrayTe

30、mp.end();Iter2+)string temp3=(*Iter2).LeftPart.substr(0,1);if(!pare(NoEndSignj)/若某產(chǎn)生式的左部為Pj,則替換,CreateFormula temp;temp=(*Iter1); temp.RightPart.replace(0,1,(*Iter2).RightPart);GR_ArrayTemp.push_back(temp);/當替換完成后,需要刪除第k條產(chǎn)生式((*Iter1)),Iter1=GR_ArrayTemp.erase(Iter1);for(Iter1=GR_ArrayTemp.begin();It

31、er1!=GR_ArrayTemp.end();Iter1+)string temp1=(*Iter1).LeftPart.substr(0,1);if(FindSign(temp1,NoEndSign)&&/若左部首字符為指定非終結(jié)符NoEndSigni,(*Iter1).LeftPart0=(*Iter1).RightPart0)/ ,且存在直接左遞歸IsIndirectLeftRecursion=true;return ;IsIndirectLeftRecursion=false;/ 能否刪除左遞歸bool CGrammar:EnableDelLeftRecursion(

32、)int Sum=GR_Array.size();for(int i=0;i<Sum;i+)/判斷能否消除左遞歸 if(GR_Arrayi.LeftPart0=GR_Arrayi.RightPart0/ 若“左部首字符=右部首字符,”&&GR_Arrayi.RightPart.length()=1)/ “且右部長度=1”,即“滿足PP回路”。/ 則再檢查是否存在與PP有相同左部首字符、且右部首字符=的產(chǎn)生式,即P形式for(int j=0;j<Sum;j+)if(GR_Arrayj.LeftPart0=GR_Arrayi.LeftPart0/相同的左部首字符,&am

33、p;&GR_Arrayj.RightPart0='')/ 且右部首字符=return false;/若存在這樣的情況,則無法消除左遞歸。退出!return true;/構(gòu)造新的非終結(jié)符,例如“E”變換為“E'”:string CGrammar:CreateNewVn(string NoEndSigntemp)return NoEndSigntemp+'''/消除直接“左”遞歸void CGrammar:DelDirectLeftRecursion(int i)string c;vector<CreateFormula>:ite

34、rator Iter1,Iter2;/ 迭代器1for(Iter1=GR_Array.begin();Iter1!=GR_Array.end();Iter1+)string temp1=(*Iter1).LeftPart.substr(0,1);if(!pare(NoEndSigni)&&/若左部首字符為指定非終結(jié)符NoEndSigni,(*Iter1).LeftPart0=(*Iter1).RightPart0)/ ,且存在直接左遞歸/(1):修改產(chǎn)生式Pa為PaP'c=CreateNewVn(NoEndSigni);for(Iter2=GR_Array.begin(

35、);Iter2!=GR_Array.end();Iter2+)string temp2=(*Iter2).LeftPart.substr(0,1);if(!pare(NoEndSigni)&&/對于左部首字符同樣=指定非終結(jié)符NoEndSigni,(*Iter2).LeftPart0!=(*Iter2).RightPart0)/但左部首字符不等于右部首字符,即不是左遞歸,例如Pa(*Iter2).RightPart+=c;/在右部尾端添補新的非終結(jié)符號,即:Pa變?yōu)镻aP'/(2):對遞歸式(*Iter1)進行改造:(*Iter1).LeftPart=c;/左部變?yōu)樾碌?/p>

36、非終結(jié)符號c,即P'(*Iter1).RightPart=(*Iter1).RightPart.erase(0,1);/右部刪除首字符,即“去除”原遞歸字符(*Iter1).RightPart+=c;/在右部尾端添加c,即P'/ 例如:PPa變?yōu)镻'aP',即變?yōu)橛疫f歸。/(3):為文法增加一條空“”產(chǎn)生式:CreateFormula temp;temp.LeftPart=(*Iter1).LeftPart;temp.RightPart=""GR_Array.push_back(temp);/(4):將P'加入非終結(jié)符集:if(!Fi

37、ndSign(c,NoEndSign)NoEndSign.push_back(c);/消除間接“左”遞歸bool CGrammar:DelIndirectLeftRecursion()/首先判斷能否消除左遞歸if(!EnableDelLeftRecursion()return false;vector<CreateFormula>:iterator Iter1,Iter2;for(int i=0;i<NoEndSign.size();i+)for(int j=0;j<i;j+)for(Iter1=GR_Array.begin();Iter1!=GR_Array.end(

38、);Iter1+)string temp1=(*Iter1).LeftPart.substr(0,1);string temp2=(*Iter1).RightPart.substr(0,1);if(!pare(NoEndSigni)/左部首字符為Pi,&&!pare(NoEndSignj)/右部首字符為Pj,即形如PiPj/注:這里,是終結(jié)符,i、j是下標。/ 尋找所有形為:Pj.的產(chǎn)生式:for(Iter2=GR_Array.begin();Iter2!=GR_Array.end();Iter2+)string temp3=(*Iter2).LeftPart.substr(0

39、,1);if(!pare(NoEndSignj)/若某產(chǎn)生式的左部為Pj,則替換,CreateFormula temp;temp=(*Iter1); temp.RightPart.replace(0,1,(*Iter2).RightPart);GR_Array.push_back(temp);/當替換完成后,需要刪除第k條產(chǎn)生式((*Iter1)),Iter1=GR_Array.erase(Iter1);DelDirectLeftRecursion(i);/消除直接左遞歸GR_Number=GR_Array.size();return true;/判斷是否含有多余產(chǎn)生式(規(guī)則)/ 多余規(guī)則(即

40、無用產(chǎn)生式)滿足下述條件:/(1)每一個非終結(jié)符號A(S除外)必須在某句型中(規(guī)則右端)出現(xiàn),/ 即若某條規(guī)則左部的非終結(jié)符A不在任何其他規(guī)則右部出現(xiàn),/ 那么所有的推導始終不會用到此規(guī)則,也就是說A是“不可到達”的。/ (2)非終結(jié)符A必須推出終結(jié)符串t來。否則在推導句子的過程中,/ 一旦使用了該規(guī)則,將推不出任何終結(jié)符號串,稱為“不可終止”的。bool CGrammar:HavingRedundance()vector<string>NoEndSignTemp;/保存能由開始符號到達的非終結(jié)符的集合vector<string>:iterator Iter1,Iter

41、3;/ 迭代器vector<CreateFormula>:iterator Iter2;/ 迭代器/第(1)種情況:刪除“不可達”產(chǎn)生式NoEndSignTemp.reserve(1000);/為NoEndSignTemp與分配存儲空間,否則可能出錯。/(A)求解能由開始符號到達的非終結(jié)符的集合:NoEndSignTemp.push_back(GR_Array0.LeftPart);for(Iter1=NoEndSignTemp.begin();Iter1!=NoEndSignTemp.end();Iter1+) for(Iter2=GR_Array.begin();Iter2!=

42、GR_Array.end();Iter2+)if(NoEndSign=NoEndSignTemp) return false;if(!(*Iter2).LeftPpare(*Iter1)for(Iter3=NoEndSign.begin();Iter3!=NoEndSign.end();Iter3+)int L=(*Iter2).RightPart.length();if(*Iter2).RightPart.find(*Iter3)<L)/如果某產(chǎn)生式的右部含有非終結(jié)符*Iter3/,且該非終結(jié)符*Iter3不在NoEndSignTemp中,則if(!FindSign(*Iter3,No

43、EndSignTemp)NoEndSignTemp.push_back(*Iter3);/ 添加到NoEndSignTemp中/(B)刪除不能由開始符號到達的非終結(jié)符引導的產(chǎn)生式:for(Iter3=NoEndSign.begin();Iter3!=NoEndSign.end();Iter3+)if(!FindSign(*Iter3,NoEndSignTemp)/若非終結(jié)符*Iter3不在NoEndSignTemp中,則return true;return false;/文法化簡,即刪除無用產(chǎn)生式。void CGrammar:MiniGrammar()vector<string>N

44、oEndSignTemp;/保存能由開始符號到達的非終結(jié)符的集合vector<string>:iterator Iter1,Iter3;/ 迭代器vector<CreateFormula>:iterator Iter2;/ 迭代器/第(1)種情況:刪除“不可達”產(chǎn)生式NoEndSignTemp.reserve(1000);/為NoEndSignTemp與分配存儲空間,否則可能出錯。/(A)求解能由開始符號到達的非終結(jié)符的集合:NoEndSignTemp.push_back(GR_Array0.LeftPart);for(Iter1=NoEndSignTemp.begin

45、();Iter1!=NoEndSignTemp.end();Iter1+) for(Iter2=GR_Array.begin();Iter2!=GR_Array.end();Iter2+)if(NoEndSign=NoEndSignTemp) return;if(!(*Iter2).LeftPpare(*Iter1)for(Iter3=NoEndSign.begin();Iter3!=NoEndSign.end();Iter3+)int L=(*Iter2).RightPart.length();if(*Iter2).RightPart.find(*Iter3)<L)/如果某產(chǎn)生式的右部

46、含有非終結(jié)符*Iter3/,且該非終結(jié)符*Iter3不在NoEndSignTemp中,則if(!FindSign(*Iter3,NoEndSignTemp)NoEndSignTemp.push_back(*Iter3);/ 添加到NoEndSignTemp中/(B)刪除不能由開始符號到達的非終結(jié)符引導的產(chǎn)生式:for(Iter3=NoEndSign.begin();Iter3!=NoEndSign.end();Iter3+)if(!FindSign(*Iter3,NoEndSignTemp)/若非終結(jié)符*Iter3不在NoEndSignTemp中,則/刪除所有左部為*Iter3的產(chǎn)生式:for

47、(Iter2=GR_Array.begin();Iter2!=GR_Array.end();Iter2+)if(!(*Iter2).LeftPpare(*Iter3)Iter2=GR_Array.erase(Iter2);/分解字符串為單個符號(包括形式為E'的符號)vector<string> CGrammar:GetSingleSign(string str)vector<string> temp1;for(int i=0;i<str.length();i+)string temp2=str.substr(i,1);if(i<str.length

48、()&&stri+1=''')temp2+=str+i;temp1.push_back(temp2); return temp1;/顯示文法(四元組形式)void CGrammar:DisplayGrammar()int sum=NoEndSign.size(),i;/顯示開始符號cout<<"G"<<StartSign<<"=("/顯示非終結(jié)符cout<<NoEndSign0;for(i=1;i<sum;i+)cout<<","

49、cout<<NoEndSigni;cout<<","/顯示終結(jié)符sum=EndSign.size(); cout<<EndSign0;for(i=1;i<sum;i+)cout<<","cout<<EndSigni;cout<<",P,"<<NoEndSign0<<"),其中P由下列產(chǎn)生式組成:"<<endl;/顯示產(chǎn)生式集合:vector<CreateFormula>:iterator I

50、ter1;for(Iter1=GR_Array.begin();Iter1!=GR_Array.end();Iter1+) cout<<""<<setw(2)<<left<<(*Iter1).LeftPart<<" " <<setw(20)<<left<<(*Iter1).RightPart<<endl;/返回文法類型int CGrammar:GetGrammarType()return GrammarTypeNum;/返回是否存在左遞歸的標識bo

51、ol CGrammar:GetHavingLeftRecursion()return IsDirectLeftRecursion|IsIndirectLeftRecursion;/返回非終結(jié)符vector<string>CGrammar:GetVN()return NoEndSign;/返回終結(jié)符vector<string>CGrammar:GetVT()return EndSign;/ 返回產(chǎn)生式數(shù)據(jù)vector<CreateFormula>CGrammar:GetCF()return GR_Array;/ 返回開始符號string CGrammar:GetStartSign()return StartSign;(

溫馨提示

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

評論

0/150

提交評論