實驗二(遞歸下降分析)_第1頁
實驗二(遞歸下降分析)_第2頁
實驗二(遞歸下降分析)_第3頁
實驗二(遞歸下降分析)_第4頁
實驗二(遞歸下降分析)_第5頁
已閱讀5頁,還剩12頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

實驗二遞歸下降語法分析實驗?zāi)康陌凑照Z言的語法要求編寫文法的規(guī)那么轉(zhuǎn)化文法的規(guī)那么,使之具有EBCF,消除左遞歸和左因子掌握編程形式的語法分析器的實現(xiàn)實驗內(nèi)容在TINY計算機(jī)語言的編譯程序的詞法分析局部實現(xiàn)的根底上,采用遞歸下降的方法實現(xiàn)語法分析,形成語法樹。語法分析的輸入是記號串,按照從左到右掃描,按照文法規(guī)那么的要求,判斷語句是否符合文法要求,如果符合要求那么形成語法數(shù),不符合那么指出原因。為了簡化程序的編寫,對語法有具體如下的要求:只有5中語句if、repeat、read、write、assignment。read只作用一個變量,實現(xiàn)輸入。write只作用一個表達(dá)式,實現(xiàn)輸出。表達(dá)式只有兩類:布爾表達(dá)式,只用于if和repeat語句的測試,算術(shù)表達(dá)式采用左結(jié)合和優(yōu)先級的方式組成。沒有變量的聲明,僅僅在賦值時采用隱性的方式說明,只有整型變量;每個語句序列采用‘;’的形式分開,最后一個語句沒有分號沒有函數(shù)或過程實驗要求要求實現(xiàn)語法分析程序的以下功能:在實現(xiàn)之前首先實現(xiàn)EBNF,消除左遞歸和左因子,為遞歸下降程序做好準(zhǔn)備對于語句和表達(dá)式采用枚舉的形式定義,形成一個統(tǒng)一的樹結(jié)點結(jié)構(gòu)把正確源程序的首先經(jīng)過詞法分析形成二元式記號提供應(yīng)語法分析程序如果出現(xiàn)錯誤,指出錯誤的位置和類型把語法樹按照樹的前序遍歷的形式把所有的結(jié)點按照某種形式輸出語法分析進(jìn)行具體的要求:語法分析的具體功能實現(xiàn)是一個函數(shù)TreeNode*parse(),分析記號串,形成一個語法數(shù)。編寫一個單獨的函數(shù)parseTree(TreeNode*)遍歷整個語法樹,把每個結(jié)點信息輸出程序:頭文件:#include<string>usingnamespacestd;enumWordType{WRONG,NUMBER,IDENTIFIER,IF,THEN,ELSE,END,//7REPEAT,UNTIL,READ,WRITE,FALSE,PLUS,SUBTRACT,MULTIPLY,//16DIVIDEY,EQUAL,LESSTHAN,SEMICOLON,FINAL,ASSIGNMENT,S_BRACKET_L,S_BRACKET_R,//24LINE_FEED,SPACE,TAB,BIG_BRACKET_L,BIG_BRACKET_R};//29voidCiFa();voidYufa2();stringIntToStr(intn);//將數(shù)字轉(zhuǎn)換成字符串intEqulStr(strings1,strings2);//比擬兩個字符串是否相等,相等返回1,否那么返回0源文件:頭文件中函數(shù):#include<iostream>#include<string>#include<sstream>#include<stdexcept>#include"head.h"usingnamespacestd;stringIntToStr(intn){ostringstreamresult;result<<n;returnresult.str();}intEqulStr(strings1,strings2){if(s1==s2)return1;elsereturn0;}詞法分析:#include<iostream>#include<iomanip>#include<ctype.h>#include<fstream>#include<string>#include"head.h"usingnamespacestd;enumCharType{ALPHABET,OTHER};enumWrongType1{ZERO,ALP_NUM,NUM_ALP,UNLEAGL_S,NO_MATCH,UNKNOW};char*Words[]={"wrong","number","identifier","if","then","else","end",//7"repeat","until","read","write","false","+","-","*",//16"/","=","<",";","$",":=","(",")",//24"\n",""," ","{","}"};//29typedefstruct{char*str;intwordtype;}Two;charArrayChar[100],cbuffer;inti=-1,numline=1,wordtype;stringLineChar;TwoT;ifstreamfp("source.txt",ios::in);ofstreamoutfile("cifa.txt",ios::out);voidCiFa(){ TwoGetToken();if(!fp) cout<<"文件翻開錯誤??!"<<endl;else { cout<<setiosflags(ios::left)<<setw(6)<<"行數(shù)"<<"("; cout<<setiosflags(ios::left)<<setw(10)<<"類別編碼"<<","; cout<<setiosflags(ios::left)<<setw(20)<<"字符"<<")"<<endl; fp.get(cbuffer);while(!fp.eof()) { GetToken(); } outfile<<numline<<","<<FINAL<<","; } cout<<"第"<<numline<<"行所有字符:"<<LineChar<<endl; fp.close(); outfile.close();}intMatch(charstr[],intchartype)//查找匹配的字符{inti;switch(chartype) {caseALPHABET:for(i=IF;i<=FALSE;i++) {if(strcmp(Words[i],str)==0)returni; }caseOTHER:for(i=PLUS;i<=S_BRACKET_R;i++) {if(strcmp(Words[i],str)==0)returni; } }return WRONG;}voidTypeWrong(intwrongtype,intline){switch(wrongtype) {caseZERO:break;caseALP_NUM: cout<<"字母后面不能緊跟數(shù)字!";break;caseNUM_ALP: cout<<"數(shù)字后面不能緊跟字母!";break;caseUNLEAGL_S: cout<<"非法特殊符號!";break;caseNO_MATCH: cout<<"沒有與第"<<line<<"行“{〞匹配的“}〞!";break;default: cout<<"其它類型錯誤!";break; }}TwoConvertTwo(charstr[],intwordtype,intwrongtype,intnumline,intline)//進(jìn)行二元轉(zhuǎn)換{ TwoT; T.wordtype=wordtype; T.str=str; cout<<setiosflags(ios::left)<<setw(6)<<numline<<"("; cout<<setiosflags(ios::left)<<setw(10) <<T.wordtype<<","; cout<<setiosflags(ios::left)<<setw(20)<<T.str<<")";if(T.wordtype==WRONG) TypeWrong(wrongtype,line); cout<<endl; outfile<<numline<<","<<T.wordtype<<",";returnT;}voidHandleAlphabet()//首字符為字母時的處理{boolmark=true;while(!fp.eof()&&isalpha(cbuffer)) { ArrayChar[++i]=cbuffer; fp.get(cbuffer); }if(isdigit(cbuffer)) { mark=false;while(!fp.eof()&&(isalpha(cbuffer)||isdigit(cbuffer))) { ArrayChar[++i]=cbuffer; fp.get(cbuffer); } } ArrayChar[i+1]='\0'; LineChar+=ArrayChar;if(mark) { wordtype=Match(ArrayChar,ALPHABET); T=ConvertTwo(ArrayChar,(IDENTIFIER>wordtype?IDENTIFIER:wordtype),ZERO,numline,numline); }else T=ConvertTwo(ArrayChar,WRONG,ALP_NUM,numline,numline);}voidHandleNumber()//首字符為數(shù)字時的處理{boolmark=true;while(!fp.eof()&&isdigit(cbuffer)) { ArrayChar[++i]=cbuffer; fp.get(cbuffer); }if(isalpha(cbuffer)) { mark=false;while(!fp.eof()&&(isalpha(cbuffer)||isdigit(cbuffer))) { ArrayChar[++i]=cbuffer; fp.get(cbuffer); } } ArrayChar[i+1]='\0'; LineChar+=ArrayChar;if(mark) T=ConvertTwo(ArrayChar,NUMBER,ZERO,numline,numline);else T=ConvertTwo(ArrayChar,WRONG,NUM_ALP,numline,numline);}voidDeleteNote()//刪除注釋{intrecord=numline;while(!fp.eof()&&cbuffer!='}') { fp.get(cbuffer);while(!fp.eof()&&cbuffer!='}') {if(cbuffer=='\n') { ArrayChar[i+1]='\0'; LineChar+=ArrayChar; cout<<"第"<<numline<<"行所有字符:"<<LineChar<<endl; LineChar=""; numline++; i=-1; fp.get(cbuffer); } ArrayChar[++i]=cbuffer; fp.get(cbuffer); } ArrayChar[i+1]='\0'; if(cbuffer=='}') { ArrayChar[++i]='}'; ArrayChar[i+1]='\0'; }else { T=ConvertTwo("",WRONG,NO_MATCH,numline,record); } } LineChar+=ArrayChar; fp.get(cbuffer);}voidHandleOther()//字符為特殊字符時的處理{ ArrayChar[++i]=cbuffer;if(ArrayChar[i]=='{')//刪除注釋 { DeleteNote(); }else//其他字符 { fp.get(cbuffer); ArrayChar[++i]=cbuffer; ArrayChar[i+1]='\0';charTemp1[2]; Temp1[0]=ArrayChar[0]; Temp1[1]='\0';if(!(wordtype=Match(ArrayChar,OTHER)))//當(dāng)雙字符沒有匹配的時候,看單字符是否有匹配的 { ArrayChar[i]='\0';if(!wordtype) wordtype=Match(Temp1,OTHER); }else { fp.get(cbuffer);while(!fp.eof()&&cbuffer!='\n'&&cbuffer!=''&&cbuffer!=' '&&!isalpha(cbuffer)&&!isdigit(cbuffer)) { ArrayChar[++i]=cbuffer; fp.get(cbuffer); } ArrayChar[i+1]='\0'; wordtype=Match(ArrayChar,OTHER); } LineChar+=ArrayChar; T=ConvertTwo(ArrayChar,wordtype,(wordtype>0?0:UNLEAGL_S),numline,numline); }}TwoGetToken(){if(cbuffer=='\n')//忽略換行符 { cout<<"第"<<numline<<"行所有字符:"<<LineChar<<endl; numline++; LineChar=""; fp.get(cbuffer); }elseif(cbuffer=='')//忽略空字符 { LineChar+=""; fp.get(cbuffer); }elseif(cbuffer==' ')//忽略制表符 { LineChar+=" "; fp.get(cbuffer); }elseif(isalpha(cbuffer))//判斷是否是字母 { HandleAlphabet(); }elseif(isdigit(cbuffer))//判斷是否是數(shù)字 { HandleNumber(); }else//其他字符 HandleOther(); i=-1;returnT;}語法分析:#include<iostream>#include<iomanip>#include<ctype.h>#include<fstream>#include<string>#include<sstream>#include<stdexcept>#include"head.h"usingnamespacestd;ifstreamfp2("cifa.txt",ios::in);intSPro();//1intSStm();//2intSStms();//3intSSta();//4intSIf();//5intSRep();//6intSAss();//7intSRea();//8intSWri();//9intSExp();//10intSCom();//11intSSim();//12intSSims();//13intSAdd();//14intSTer();//15intSTers();//16intSMul();//17intSFac();//18charlastline[4],line[4],ch2[4];boolOK=true;voidGetWord(char*line,char*ch2){ strcpy_s(lastline,line); fp2.getline(line,3,','); fp2.getline(ch2,3,',');}voidYufa2(){ CiFa(); if(!fp2) cout<<"文件翻開錯誤?。?<<endl; else { cout<<"文件翻開成功!"<<endl; GetWord(line,ch2); while(!EqulStr(ch2,IntToStr(FINAL))) SPro(); if(OK) cout<<"OK源文件符合該文法!"<<endl; else cout<<"Wrong源文件不符合該文法!"<<endl; } fp2.close();}intSPro()//1{ if(SStm()) return1; //如果此次讀入的第一個字符不是開始符號,那么繼續(xù)讀取下一個 cout<<"第"<<lastline<<"行錯誤!"<<endl; GetWord(line,ch2); OK=false; return0;}intSStm()//2{ if(SSta()) { if(SStms()) return1; else cout<<"第"<<lastline<<"行缺少語句的結(jié)束符;!"<<endl; OK=false; return1; } return0;}intSStms()//3{ if(EqulStr(ch2,IntToStr(SEMICOLON))) { GetWord(line,ch2); if(SSta()) { if(SStms()) return1; else cout<<"第"<<lastline<<"行缺少有效的語句!"<<endl; } else cout<<"第"<<lastline<<"行;后面沒有有效的語句!"<<endl; OK=false; return1; } elseif(EqulStr(ch2,IntToStr(END))||EqulStr(ch2,IntToStr(ELSE)) ||EqulStr(ch2,IntToStr(UNTIL))||EqulStr(ch2,IntToStr(FINAL))) return1; return0;}intSSta()//4{ if(SIf()||SRep()||SAss()||SRea()||SWri()) return1; return0;}intSIf()//5{ if(EqulStr(ch2,IntToStr(IF))) { GetWord(line,ch2); if(SExp()) { if(EqulStr(ch2,IntToStr(THEN))) { GetWord(line,ch2); if(SStm()) { if(EqulStr(ch2,IntToStr(END))) { GetWord(line,ch2); return1; } elseif(EqulStr(ch2,IntToStr(ELSE))) { GetWord(line,ch2); if(SStm()) { if(EqulStr(ch2,IntToStr(END))) { GetWord(line,ch2); return1; } else { cout<<"第"<<lastline<<"行缺少語句的結(jié)束符end!"<<endl; } } else { cout<<"第"<<lastline<<"行else后面沒有有效的語句!"<<endl; } } else { cout<<"第"<<lastline<<"行缺少語句的結(jié)束符end!"<<endl; } } else { cout<<"第"<<lastline<<"行缺少關(guān)鍵字else!"<<endl; } } else { cout<<"第"<<lastline<<"行then后面沒有有效的語句!"<<endl; } } else cout<<"第"<<lastline<<"行if后面沒有有效的表達(dá)式!"<<endl; OK=false; return1; } return0;}intSRep()//6{ if(EqulStr(ch2,IntToStr(REPEAT))) { GetWord(line,ch2); if(SStm()) { if(EqulStr(ch2,IntToStr(UNTIL))) { GetWord(line,ch2); if(SExp()) return1; else cout<<"第"<<lastline<<"行until后面沒有有效的表達(dá)式!"<<endl; } else { cout<<"第"<<lastline<<"行缺少關(guān)鍵字until!"<<endl; } } else cout<<"第"<<lastline<<"行repeat后面沒有有效的語句!"<<endl; OK=false; return1; } return0;}intSAss()//7{ if(EqulStr(ch2,IntToStr(IDENTIFIER))) { GetWord(line,ch2); if(EqulStr(ch2,IntToStr(ASSIGNMENT))) { GetWord(line,ch2); if(SExp()) return1; else cout<<"第"<<lastline<<"行:=后面沒有有效的表達(dá)式!"<<endl; } else { cout<<"第"<<lastline<<"行缺少關(guān)鍵字:=!"<<endl; } OK=false; return1; } return0;}intSRea()//8{ if(EqulStr(ch2,IntToStr(READ))) { GetWord(line,ch2); if(EqulStr(ch2,IntToStr(IDENTIFIER))) { GetWord(line,ch2); return1; } else { cout<<"第"<<lastline<<"行read后面沒有有效的標(biāo)識符!"<<endl; } OK=false; return1; } return0;}intSWri()//9{ if(EqulStr(ch2,IntToStr(WRITE))) { GetWord(line,ch2); if(SExp()) return1; else cout<<"第"<<lastline<<"行write后面沒有有效的表達(dá)式!"<<endl; OK=false; return1; } return0;}intSExp()//10{ if(SSim()) { if(SCom()) { if(SSim()) return1; else cout<<"第"<<lastline<<"行缺少〔或者數(shù)字或者標(biāo)識符!"<<endl; OK=false; } return1; } return0;}intSCom()//11{ if(EqulStr(ch2,IntToStr(LESSTHAN))||EqulStr(ch2,IntToStr(EQUAL))) { GetWord(line,ch2); return1; } return0;}intSSim()//12{ if(STer()) { if(SSims()) return1; else cout<<"第"<<lastline<<"行缺少有效的關(guān)鍵字!"<<endl; OK=false; return1; } return0;}intSSims()//13{ if(SAdd()) { if(STer()) { if(SSims()) return1; else cout<<"第"<<lastline<<"行缺少有效的關(guān)鍵字!"<<endl; } else cout<<"第"<<lastline<<"行缺少〔或者數(shù)字或者標(biāo)識符!"<<endl; OK=false; return1; } else if(EqulStr(ch2,IntToStr(THEN))||EqulStr(ch2,IntToStr(END))||EqulStr(ch2,IntToStr(ELSE)) ||EqulStr(ch2,IntToStr(UNTIL))||EqulStr(ch2,IntToStr(S_BRACKET_R))||EqulStr(ch2,IntToStr(LESSTHAN)) ||EqulStr(ch2,IntToStr(EQUAL))||EqulStr(ch2,IntToStr(FINAL))||EqulStr(ch2,IntToStr(SEMICOLON))) return1; return0;}intSAdd()//14{ if(EqulStr(ch2,IntToStr(PLUS))||EqulStr(ch2,IntToStr(SUBTRACT))) { GetWord(line,ch2); return1; } return0;}intSTer()//15{ if(SFac()) { if(STers()) return1; else cout<<"第"<<lastline<<"行缺少有效的關(guān)鍵字!"<<endl; OK=false; return1; } return0;}intSTers()//16{ if(SMul()) { if(SFac()) { if(STers()) return1; else cout<<"第"<<lastline<<"行缺少有效的表

溫馨提示

  • 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

提交評論