




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
..編譯原理實驗報告實驗名稱:編寫詞法分析程序_______實驗類型:設計型實驗指導專業____學號:實驗地點:實驗成績:日期:2017年4月15日實驗一編寫語法分析程序實驗目的通過設計、調試詞法分析程序,掌握詞法分析程序的設計工具,即有窮自動機,進一步理解自動機理論;掌握正則文法和正則表達式轉換成有窮自動機的方法及有窮自動機的實現方法;會確定詞法分析程序的輸出形式及標識符與關鍵字的區分方法;加深對課堂教學的理解,提高詞法分析方法的實踐能力,掌握使用實驗環境的技能技巧以及程序的調試方法。二、實驗設計1、寫出TEST語言每條詞法規則對應的正則文法或者正則表達式標識符:字母打頭,后接任意字母或數字。正則表達式:<a|b|……|z|A|B……|Z><0|1|……|9|a|b|……|z|A|B……|Z>*保留字:標符的子集,包括:if,else,for,while,do,int,write,read。正則表達式:if|else|for|while|do|int|write|read無符號整數:由數字組成,但最高位不能為0,允許一位的0。正則表達式:<<1……|9><0|1|……|9>*>|0分界符:<、>、;、{、}正則表達式:<|>|;|{|}運算符:+、-、*、/、=、<、>、>=、<=、!=、==正則表達式:+|-|*|/|=|<|>|>=|<=|!=|==注釋符:/**/正則表達式:/*<沒有連續的*/的任意字符串|?>*/2、對每個文法或者正則表達式分別構造NFA標識符:<a|b|……|z|A|B……|Z><0|1|……|9|a|b|……|z|A|B……|Z>*無符號整數:<<1|2|……|9><0|1|……|9>*>|0分界符:<|>|;|{|}運算符:+|-|*|/|=|<|>|>=|<=|!=|==注釋符:/*<沒有連續的*/的任意字符串|?>*/3、將NFA合并,確定化,化簡得到最終的DFA。NFA:DFA:三、實驗過程1、完成整個實驗的先后步驟根據TEST語言的詞法規則,分別寫出每條規則的正則文法或者正則表達式;將每一個正則文法或者正則表達式轉換為NFA;將多個NFA合并后進行確定化并化簡;根據化簡后的DFA畫出流程圖;參閱教材PP.69-71的TEST語言語法規則,確定單詞分類、單詞輸出方案;編寫詞法分析程序;對下面的TEST語言源程序進行詞法分析,將合法單詞存入lex.txt,并報告詞法錯誤及其位置。注:不能修改源程序{/*Thisatestprogram.*/intabc;int123;intA$;inti;intn;intb,c;int2a;inta2;readn;n=012345;for<i=1;i<=n;i=i+1>{abc=abc+i;}if<i!=n>n=n+i;if<!n>b=b+c;/*Theloopendedwriteabc;}2、實驗調試記錄〔問題表現,分析原因,解決方案,解決結果問題表現:不能處理除號不能處理不完整的注釋符對于"0123"這類字符串的處理不正確,我之前處理為直接報錯說一位以上的數字首位不能為0分析原因:問題1,2的原因都是在"/"符號處理時出現的問題導致的,程序中出現bug使得一遇到‘/’就會進入死循環。問題3,不應該直接報錯說一位以上的數字首位不能為0,遇到0應該直接輸出0這個單詞,再接著讀數字。解決方案:對于問題1,2,重新梳理邏輯,一步一步對照流程圖和DFA來調試修改代碼。對于問題3,遇到0應該直接輸出0這個單詞,再接著讀數字。解決結果:成功解決了程序遇到‘/’進入死循環問題和"0123"這類字符串的處理。三、實驗結果列出實驗結果并進行分析〔含分步測試結果。lex.txt文件〔存放編譯的合法內容內容:1 { {2 /*Thisatestprogram.*/ /*Thisatestprogram.*/3 int int3 ID abc3 ; ;4 int int4 NUM 1234 ; ;5 int int5 ID A5 ; ;6 int int6 ID i6 ; ;7 int int7 ID n7 ; ;8 int int8 ID b8 ID c8 ; ;9 int int9 NUM 29 ID a9 ; ;10 int int10 ID a210 ; ;11 read read11 ID n11 ; ;12 ID n12 = =12 NUM 012 NUM 1234512 ; ;13 for for13 < <13 ID i13 = =13 NUM 113 ; ;13 ID i13 <= <=13 ID n13 ; ;13 ID i13 = =13 ID i13 + +13 NUM 113 > >14 { {15 ID abc15 = =15 ID abc15 + +15 ID i15 ; ;16 } }17 if if17 < <17 ID i17 != !=17 ID n17 > >17 ID n17 = =17 ID n17 + +17 ID i17 ; ;18 if if18 < <18 ID n18 > >18 ID b18 = =18 ID b18 + +18 ID c18 ; ;四、討論與分析你的編寫詞法分析程序滿足最長匹配原則嗎?如果滿足請給出你的實現方案。如果不滿足請給出改進方案。答:不滿足,我的處理先后順序是:標識符或保留字、數字、分界符、運算符〔除開/、除或者注釋,我應該吧注釋放在前面,因為一般來說注釋都比其它類型符號長些。改進措施便是將注釋這一條詞法規則最早處理。給出你的單詞分類方案,并說明理由。答:根據TEST語言可將單詞分為六類:標識符:字母打頭,后接任意字母或數字。保留字:標識符的子集,包括:if,else,for,while,do,int,write,read。無符號整數:由數字組成,但最高位不能為0,允許一位的0。分界符:<、>、;、{、}運算符:+、-、*、/、=、<、>、>=、<=、!=、==注釋符:/**/構建詞法分析程序一般過程是怎樣的?答:構建詞法分析程序的一般過程:根據詞法規則寫出正則文法或者正則文法。為每一個正則表達式構造一個NFA,然后將多個NFA合并為一個NFA將NFA轉化成DFA,并且化簡最小化DFA確定單詞的輸出形式根據化簡后的DFA和單詞輸出程序構造詞法分析程序〔主要部分:通過實驗對課程知識點的理解;回答實驗指導書的實驗思考提出的問題等五、附錄:關鍵代碼〔給出適當注釋,可讀性高#include<iostream>#include<fstream>#include<stdio.h>#include<stdlib.h>#include<string>usingnamespacestd;constintKWN=8;//關鍵字的個數constintMAXSIZE=400;//標識符最長個數charkword[KWN][10]={//關鍵字 "if", "else", "for", "while", "do", "int", "read", "write"}; intline=1;//行號 interrors=0; //記錄錯誤個數 ofstreamfout;//輸出文件流 ifstreamfin; //輸入文件流 ofstreamlexout; //存放合法單詞的文件流 chartype[6][30]={ "ID", "保留字", "NUM", "分界符", "運算符", "注釋符"}; intmain<> { intTEST<>; //函數聲明 TEST<>; if<errors==0> { cout<<"編譯成功。"<<endl; } else { cout<<"編譯失敗。共發現"<<errors<<"個錯誤!"<<endl; } return0; } ////判斷是否為字母 intis_Char<charch> { if<<ch>='a'&&ch<='z'>||<ch>='A'&&ch<='Z'>> { return1; } return0; } ////判斷是否為無符號整數 intis_Uint<charch> { if<'0'<=ch&&ch<='9'> { return1; } return0; } ////判斷是否為分界符 intis_Deli<charch> { if<ch=='<'||ch=='>'||ch==';'||ch=='{'||ch=='}'> { return1; } return0; } ////判斷是否為操作符 intis_Oper<charch> { charOperater[10]="+-*!=><";//沒有考慮/號 for<inti=0;i<8;i++> { if<ch==Operater[i]> { return1; } } return0; } ////輸入控制 intin<char&ch> { fin.get<ch>; if<'\n'==ch> { line++; } if<fin.eof<>> { ch=EOF; } return1; } ////輸出控制 voidout<char*type,char*buf> { if<strcmp<type,"ID">==0||strcmp<type,"NUM">==0> lexout<<line<<" "<<type<<" "<<buf<<endl; else lexout<<line<<" "<<buf<<" "<<buf<<endl; //cout<<type<<": "<<buf<<endl; } ////編譯程序主要的函數 intTEST<> { intevent=0;//用于判斷輸入是否為文件末 //charfilename[300];//存儲文件的路徑 //////打開文件的操作 //打開編譯程序存放合法單詞的文件 lexout.open<"lex.txt">; //打開用戶的文件 //cout<<"請輸入要編譯的文件的路徑:"<<endl;reinput_in: // cin.get<filename,300,'\n'>; //charfilename[300]={"D:\Software\MicrosoftVisualC++6.0\MicrosoftVisualStudio\MyProjects\編譯原理實驗一\in.txt"}; fin.open<"in.txt">; if<fin==NULL> { cout<<"文件打開失敗,請重新輸入文件路徑:"<<endl; gotoreinput_in; } //cout<<"請輸入詞法分析結果文件存儲路徑:"<<endl;reinput_out: cin.clear<>;//清理輸出緩沖 cin.sync<>;//清空流 // cin.get<filename,300,'\n'>; // charfilename[300]={"D:\Software\MicrosoftVisualC++6.0\MicrosoftVisualStudio\MyProjects\編譯原理實驗一\out.txt"}; fout.open<"out.txt">; if<fout==NULL> { cout<<"文件打開失敗,請重新輸入文件路徑:"<<endl; gotoreinput_out; } //////開始判斷 charbuf[300]; charch; cin.clear<>;//清理輸出緩沖 cin.sync<>;//清空流 in<ch>; while<!fin.eof<>> { while<ch==''||ch=='\n'||ch=='\t'||ch=='\r'> { in<ch>; } //判斷是否為標識符或保留字 if<is_Char<ch>> { intt=0; while<is_Char<ch>> { buf[t++]=ch; in<ch>; } buf[t]='\0'; //判斷保留字 intj=0; for<;j<KWN;j++> { if<strcmp<kword[j],buf>==0> { out<type[1],buf>; break; } } //ID標識符 if<j>=KWN> { while<is_Char<ch>||is_Uint<ch>> { buf[t++]=ch; in<ch>; } buf[t]='\0'; out<type[0],buf>; } } //判斷是否為數字 elseif<is_Uint<ch>> { intt=0; while<is_Uint<ch>> { buf[t++]=ch; in<ch>; } buf[t]='\0'; if<t==1> { out<type[2],buf>; } elseif<buf[0]=='0'> { inti=-1; while<i<t&&buf[++i]=='0'> { out<type[2],&"0">; } out<type[2],buf+i>; } else { out<type[2],buf>; } } //判斷是否為分界符 elseif<is_Deli<ch>> { buf[0]=ch; buf[1]='\0'; out<type[3],buf>; in<ch>; } //判斷是否為運算符〔除開/ elseif<is_Oper<ch>> { if<ch=='+'||ch=='-'||ch=='*'> { buf[0]=ch; buf[1]='\0'; out<type[4],buf>; in<ch>; } elseif<ch=='!'> { buf[0]=ch; in<ch>; if<ch=='='> { buf[1]=ch; buf[2]='\0'; out<type[4],buf>; in<ch>; } else { cout<<"error"<<++errors<<"line"<<line<<":'!'不合法的符號!"<<endl; } } elseif<ch=='>'||ch=='<'||ch=='='> { buf[0]=ch; in<ch>; if<ch=='='> { buf[1]=ch; buf[2]='\0'; out<type[4],buf>; in<ch>; } else { buf[1]='\0'; out<type[4],buf>; } } } elseif<ch=='/'>//判斷是除還是注釋 { intt=0; buf[t++]=ch; charch0; in<ch0>; while<1> { if<ch0==EOF> { cout<<"error"<<++errors<<"line"<<line<<":匹配錯誤,缺少*/"<<endl; break; } ch=ch0; buf[t++]=ch; in<ch0>; if<ch=='*'&&ch0=='/'> { buf[t++]=ch0; buf[t]='\0'; out<type[5],buf>;
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 商品代理采購合同范本
- 河北省保定市2025屆高三下學期一模試題 地理 含解析
- 創新創業基礎教程 課件 模塊三 創業團隊組建
- 不跪的中國人課件
- 西藏昌都地區昌都縣2025年數學三下期末質量跟蹤監視模擬試題含解析
- 云南農業職業技術學院《中國現代文學Ⅱ》2023-2024學年第一學期期末試卷
- 濟源職業技術學院《農業機械與信息技術》2023-2024學年第二學期期末試卷
- 長沙理工大學城南學院《復合材料力學與結構設計基礎》2023-2024學年第二學期期末試卷
- 遼寧省大連市高新區2025年小升初數學綜合練習卷含解析
- 沈陽航空航天大學《鋼琴(3)》2023-2024學年第二學期期末試卷
- 課文《牧場之國》的教學反思
- 天藍色商務發展歷程時間軸PPT模板課件
- T∕CADERM 3035-2020 嚴重創傷院內救治流程和規范
- 外墻憎水巖棉保溫板施工方案doc
- 聯想集團財務風險分析及對策論文財務管理專業
- 阿丁尿床了(2)
- 工會會計報表完整版(內有6張表)
- 雙堿法脫硫設計計算
- 增值稅銷售貨物或者提供應稅勞務清單(標準模板)
- 醫用耗材分類目錄 (低值 ╱ 高值)
- competition-model
評論
0/150
提交評論