東南大學(xué)編譯原理詞法分析器實(shí)驗報告.doc
《東南大學(xué)編譯原理詞法分析器實(shí)驗報告.doc》由會員分享,可在線閱讀,更多相關(guān)《東南大學(xué)編譯原理詞法分析器實(shí)驗報告.doc(11頁珍藏版)》請在裝配圖網(wǎng)上搜索。
詞法分析設(shè)計1. 實(shí)驗?zāi)康耐ㄟ^本實(shí)驗的編程實(shí)踐,了解詞法分析的任務(wù),掌握詞法分析程序設(shè)計的原理和構(gòu)造方法,對編譯的基本概念、原理和方法有完整的和清楚的理解,并能正確地、熟練地運(yùn)用。2. 實(shí)驗內(nèi)容用C+語言實(shí)現(xiàn)對C+語言子集的源程序進(jìn)行詞法分析。通過輸入源程序從左到右對字符串進(jìn)行掃描和分解,依次輸出各個單詞的內(nèi)部編碼及單詞符號自身值;若遇到錯誤則顯示“Error”,然后跳過錯誤部分繼續(xù)顯示;同時進(jìn)行標(biāo)識符登記符號表的管理。 3.實(shí)驗原理本次實(shí)驗采用NFA-DFA-DFA0的過程: 對待分析的簡單的詞法(關(guān)鍵詞/id/num/運(yùn)算符/空白符等)先分別建立自己的FA,然后將他們用產(chǎn)生式連接起來并設(shè)置一個唯一的開始符,終結(jié)符不合并。待分析的簡單的詞法(1)關(guān)鍵字: asm,auto,bool,break,case,catch,char,class,const,const_cast等(2)界符(查表) ;,(,),(3) 運(yùn)算符*,/,%,+,-,&,|,+,-,+=,-=,*=,/=,%=,&=,=,|=relop:(4) 其他單詞是標(biāo)識符(ID)和整型常數(shù)(SUM),通過正規(guī)式定義。 id/keywords: digit: (5) 空格有空白、制表符和換行符組成??崭褚话阌脕矸指鬒D、SUM、運(yùn)算符、界符和關(guān)鍵字,詞法分析階段通常被忽略。 空白、制表符和換行符:4.相關(guān)自動機(jī)描述DFA:DFA0: 5. 流程圖5.核心數(shù)據(jù)結(jié)構(gòu)描述(1)生成的token序列由name、type、attr保存。struct token string name; string type; int attr; ; (2)本文的大多數(shù)數(shù)據(jù)結(jié)構(gòu)都用map來保存,優(yōu)點(diǎn)是查找方便,大大提高時間復(fù)雜度。 map Keywords; /保存關(guān)鍵字 map Sep; /保存界符map Relop; /保存比較運(yùn)算符map Op; /保存其他運(yùn)算符mapid; /保存輸入字符串中的idmapnum; /保存數(shù)字vectorToken; /保存token序列,大小未知,所以采用vector保存6.核心算法描述(1)void addToken(string s,int type)s為找到的字符串,type為可能類型。 將分析出來的token()序列添加到Token序列表中。如果是類型為1,查看關(guān)鍵詞表,若找到,其類型為關(guān)鍵詞并將其以類型為關(guān)鍵詞存儲到Token表中;若未找到,則查找id表,若找到,說明該id已經(jīng)出現(xiàn)過,否則添加新的id到id表中,將該i字符串以類型為id添加到Token表中。如果類型為2,在界符表中查找,如果找到以類型為界符存儲到Token表中,同理其他幾種類型??赡茴愋蜑?-5,如果出現(xiàn)其他類型表示是詞法分析器中發(fā)現(xiàn)額錯誤,將錯誤信息記錄下來。void addToken(string s,int type) switch(type)case 1: l_it=Keywords.find(s); if (l_it!=Keywords.end() token t=s,keywords,l_it-second; Token.push_back(t); elsel_it=id.find(s); if (l_it=id.end() ids=idNum; token t=s,id,idNum+; Token.push_back(t); else token t=s,id,l_it-second; Token.push_back(t); break;case 2:l_it=Sep.find(s); if (l_it!=Sep.end() token t=s,separatrix,l_it-second; Token.push_back(t); break;case 3:l_it=Op.find(s); if (l_it!=Op.end() token t=s,op,l_it-second; Token.push_back(t); break;case 4:l_it=Relop.find(s); if (l_it!=Relop.end() token t=s,relop,l_it-second; Token.push_back(t); break;case 5: l_it=num.find(s); if (l_it=num.end() nums=nNum; token t=s,num,nNum+; Token.push_back(t); else token t=s,num,l_it-second; Token.push_back(t); break; default: /error token t=s,id,-1; Token.push_back(t); break; (2) void lexical() 詞法分析器,按字符讀入文法并對其進(jìn)行處理。從狀態(tài)0開始處理,如果是空白符則一直在狀態(tài)0,如果第一個字符為字母,繼續(xù)往后尋找,直至不是字母或是數(shù)字結(jié)束;若第一個字符為數(shù)字,將其拼湊成一個數(shù)字,數(shù)字可以有小數(shù)點(diǎn)等,詳細(xì)見狀態(tài)轉(zhuǎn)換圖,注意以數(shù)字開頭容易出現(xiàn)一種例如3a類型的錯誤,所以以數(shù)字開頭的一定要往下多找一個,看最后一個數(shù)字后面是否為空白符或界符或者其他允許出現(xiàn)的符號,如果后面緊跟著字母則報錯。如上同理分析運(yùn)算符等。注意每次處理完遇到一個字符串都要將其送到addToken()添加到Token表中并回到狀態(tài)0,繼續(xù)往下處理。 void lexical()fstream ln(E:ln.txt); char ch,tempch; int state=0; string s=,key=; while(!ln.eof() switch(state) case 0: ch=ln.get(); s=ch; if (ch=13|ch=10|ch=32|ch=9) state=0; s=; else if (ch=) state=9;else if (isLetter(ch) state=13;else if (isDigit(ch) state=15; else if (ch=+|ch=-|ch=*|ch=/|ch=&|ch=|) state=20; tempch=ch; else if (ch=) state=44; else if (isSep(ch)!=-1) state=47;else if (isOp(s)!=-1) state=48; else if (isRelop(s)!=-1) state=49; else state=50; /error break; case 1: ch=ln.get(); if(ch=|ch=) state=2; else if(ch=) state=11; else state=12; break;case 10: s+=ch; addToken(s,4); state=0;break;case 11:s+=ch;addToken(s,3); state=0; break; case 12: /* state=0;addToken(s,4); ln.seekg(-1,ios:cur); break;case 13: ch=ln.get(); if(isDigit(ch)|isLetter(ch) s+=ch; else state=14; break; case 14: /* state=0;addToken(s,1); ln.seekg(-1,ios:cur);break;case 15: ch=ln.get(); if (isDigit(ch) s+=ch; else if (ch=.)s+=ch; state=16; else state=18; break; case 16: ch=ln.get(); s+=ch;if (isDigit(ch) state=17; else state=50; /error break;case 17: ch=ln.get(); if (isDigit(ch) s+=ch; state=17; else state=18; break; case 18: /* if (isLetter(ch) s+=ch; state=50; elseaddToken(s,5); ln.seekg(-1,ios:cur); state=0; break;case 20: ch=ln.get(); if(ch=tempch|ch=) state=21; else state=23; break;case 21: s+=ch; addToken(s,3); state=0; break; case 23:addToken(s,3); ln.seekg(-1,ios:cur); state=0; break; case 44: ch=ln.get(); if (ch=) state=45; else state=46; break;case 45: s+=ch; addToken(s,3); break; case 46:addToken(s,3); ln.seekg(-1,ios:cur); break;case 47:addToken(s,2); state=0; break; case 48:addToken(s,3); state=0;break; case 49: addToken(s,4); state=0; break; case 50: /error while(ch=ln.get()!=EOF) if(isSep(ch)!=-1|ch=13|ch=10|ch=32|ch=9) break; else s+=ch; addToken(s,6); /error ln.seekg(-1,ios:cur); state=0; break;default: break; 7.測試用例待測字符串:void fun() int a=2,b=3,3a; a+;b-; a+=b; b*=a; int c=a+4; int d=b*5; 產(chǎn)生結(jié)果在out.txt中(注意,無論輸入輸出文件都要保存在E盤根目錄下) 8.出現(xiàn)的問題與解決方案 本實(shí)驗的難點(diǎn)就是進(jìn)行有效地進(jìn)行狀態(tài)如轉(zhuǎn)換,先對每一個簡單部分,如空白符、id、digit等畫出自動機(jī)狀態(tài),然后由NFA-DFA,添加一個唯一的初始狀態(tài),產(chǎn)生式連接。再將DFA中等價的狀態(tài)合并最后變成DFA0。這樣便大大簡化了代碼量,也使得邏輯思維更加清晰。 9.自我體會 將理論運(yùn)用到實(shí)際,不僅可以幫我們更好地復(fù)習(xí)理論知識,還可以讓我們發(fā)發(fā)掘到一些更深刻層面上的東西。通過本次實(shí)驗,我深入了解了詞法分析的過程,對NFA,DFA,DFA0之間的轉(zhuǎn)換也更能更加熟練地運(yùn)用。這次實(shí)驗還有許多需要加強(qiáng)的地方,比如還可以對id的類型進(jìn)行明確分類,是函數(shù)還是變量,是什么類型的,返回類型是什么等等。之后有機(jī)會的話,我一定會更加深入的研究,將這個實(shí)驗更加完善。- 1.請仔細(xì)閱讀文檔,確保文檔完整性,對于不預(yù)覽、不比對內(nèi)容而直接下載帶來的問題本站不予受理。
- 2.下載的文檔,不會出現(xiàn)我們的網(wǎng)址水印。
- 3、該文檔所得收入(下載+內(nèi)容+預(yù)覽)歸上傳者、原創(chuàng)作者;如果您是本文檔原作者,請點(diǎn)此認(rèn)領(lǐng)!既往收益都?xì)w您。
下載文檔到電腦,查找使用更方便
9.9 積分
下載 |
- 配套講稿:
如PPT文件的首頁顯示word圖標(biāo),表示該P(yáng)PT已包含配套word講稿。雙擊word圖標(biāo)可打開word文檔。
- 特殊限制:
部分文檔作品中含有的國旗、國徽等圖片,僅作為作品整體效果示例展示,禁止商用。設(shè)計者僅對作品中獨(dú)創(chuàng)性部分享有著作權(quán)。
- 關(guān) 鍵 詞:
- 東南大學(xué) 編譯 原理 詞法 分析器 實(shí)驗 報告
鏈接地址:http://www.szxfmmzy.com/p-6481154.html