版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、<p> 2011—2012學(xué)年第一學(xué)期</p><p><b> 目 錄</b></p><p> 第 1 節(jié)課程設(shè)計目的1</p><p> 第 2 節(jié)課程設(shè)計要求1</p><p> 第 3 節(jié)課程設(shè)計內(nèi)容2</p><p> 第 4 節(jié) 狀態(tài)轉(zhuǎn)換圖
2、4</p><p> 第 5 節(jié) 實現(xiàn)工具4</p><p> 第 6 節(jié)實現(xiàn)函數(shù)4</p><p> 第 7 節(jié)測試結(jié)果5</p><p> 第 8 節(jié)實驗源代碼6</p><p> 第 9 節(jié)參考文獻(xiàn)9</p><p><b> 致謝</b
3、></p><p><b> 感設(shè)計目的</b></p><p> ?、倮斫庠~法分析器的基本功能。詞法分析的任務(wù)是:從左至右逐個字符地對源程序進(jìn)行掃描,產(chǎn)生一個個的單詞符號(token),把作為字符串的源程序改造成 單詞符號串的中間程序。因此,詞法分析是編譯的基礎(chǔ)。</p><p> ②理解詞法規(guī)則的描述方法。程序設(shè)計語言一般可以用
4、標(biāo)識符、關(guān)鍵字、運算符、分隔符、常量、字符串和注釋符來描述</p><p> ?、芾斫鉅顟B(tài)轉(zhuǎn)換圖及其實現(xiàn)。一個狀態(tài)轉(zhuǎn)換圖可用于識別(或接受)一定的字符。 大多數(shù)程序語言的單詞符號都可以用轉(zhuǎn)換圖予以識別。 轉(zhuǎn)換圖非常易于用程序?qū)崿F(xiàn),最簡單的辦法是讓每個狀態(tài)結(jié)對應(yīng)一小段程序。</p><p> ?、苣軌蚓帉懞唵蔚脑~法分析器。</p><p><b> 2.課
5、程設(shè)計的要求</b></p><p> 手工構(gòu)造一個簡單的詞法分析程序, 能夠識別標(biāo)識符、整數(shù)、關(guān)鍵字、算符、界符。</p><p> ①畫出識別單詞的狀態(tài)轉(zhuǎn)換圖。</p><p> (若狀態(tài)轉(zhuǎn)換圖過于復(fù)雜,可以只畫出主要部分;若依舊復(fù)雜,可只識別標(biāo)識符和整數(shù))</p><p> ?、诟鶕?jù)狀態(tài)轉(zhuǎn)換圖手工構(gòu)造詞法分析程序。從以
6、下方法中選一:</p><p> 詞法分析器作為獨立的一遍。</p><p> 詞法分析結(jié)果輸出到屏幕上或存入文件。</p><p> 詞法分析器作為一個子程序被語法分析器調(diào)用。</p><p> 每次調(diào)用返回一個單詞</p><p> 同時將單詞及屬性存入符號表</p><p>
7、③ 實現(xiàn)狀態(tài)轉(zhuǎn)換圖。從以下方法中選一:</p><p><b> 直接轉(zhuǎn)向法</b></p><p><b> 表驅(qū)動法</b></p><p><b> 四、選做實驗</b></p><p><b> ? 使用緩沖技術(shù)</b></p>
8、<p><b> 3.課程設(shè)計內(nèi)容</b></p><p> 程序語言的單詞符號一般可分為下列五種。</p><p><b> (1)關(guān)鍵字 </b></p><p> 是由程序語言定義的具有固定意義的標(biāo)志符。本程序定義 char,short,int,unsigned,long,float,doub
9、le,struct,union,void,enum,const,typedef,auto,static,break,case,continue,default,do,else,for,if,return,switch,while,sizeof,printf,FILE,fopen,NULL,fclose,exit,read,closef,printf為關(guān)鍵字。</p><p><b> ?。?)標(biāo)識符&l
10、t;/b></p><p> 用來表示各種名字,如變量名、數(shù)組名、過程名等等。</p><p><b> ?。?)常數(shù)</b></p><p> 常數(shù)的類型一般有整型、實型、布爾型、文字型等等。例如,100,3.14159。</p><p><b> ?。?)運算符</b></p&g
11、t;<p> 如+、-、*、/、>=、<=、== 等等</p><p><b> ?。?)界符</b></p><p> 如[、]、{、}、(、)、;、,、.等等。</p><p><b> 具體實現(xiàn)過程:</b></p><p> 用c++編寫詞法分析程序,從文件
12、中讀入預(yù)分析的源程序經(jīng)詞法分析將結(jié)果寫入指定文件中。</p><p> 在設(shè)計中預(yù)分析文件保存在test.txt中,輸出結(jié)果保存在result.txt中。</p><p><b> 本程序?qū)崿F(xiàn)了</b></p><p> 將詞法分析器作為獨立的一遍,詞法分析結(jié)果存入文件。</p><p> 用直接轉(zhuǎn)向法實現(xiàn)狀態(tài)轉(zhuǎn)
13、換圖。</p><p><b> ?使用緩沖技術(shù)。</b></p><p> 本程序能夠識別簡單的運算符,界符,常數(shù),標(biāo)示符和關(guān)鍵字。其中關(guān)鍵字由程序所給的關(guān)鍵字表kt(key table)內(nèi)容指定。如有未涉及的關(guān)鍵字還可以通過修改程序中表內(nèi)容擴展。對未定義的字符(不屬于界符,運算符和常數(shù))輸出 并顯示為“其他字符”。文中特別定義了注釋符號,換行符號和空格。在程序
14、設(shè)計工程中一開始未注意將當(dāng)前指針后退一位的情況,在輸出程序結(jié)果時發(fā)現(xiàn)一些字符缺漏。通過查資料【1】發(fā)現(xiàn)了將指針后移的用法并解決了這個問題。設(shè)計過程中牽涉到對文件的使用如c_str(),ios:binary的用法,get()函數(shù)的用法,fstream的兩個類ifstream和ofstream的用法【2】實現(xiàn)文件的讀寫操作。</p><p> 為了分析大于4kb的程序本程序使用了著名的雙緩沖技術(shù)。設(shè)計思想如下<
15、;/p><p><b> 4.狀態(tài)轉(zhuǎn)換圖如下</b></p><p><b> 5.實驗工具</b></p><p> Vc++6.0 ,win7畫圖工具,</p><p><b> 6. 實現(xiàn)函數(shù)</b></p><p> void get_ch
16、ar (); //用于從buffer讀取一個字符到C </p><p> int letter (int C); //判斷是否是字母 </p><p> int digit (int C); //判斷時候是數(shù)字或者小數(shù)點 </p><p> int underline (int C);
17、 //判斷時候是下劃線 </p><p> int reserve (string token); //判斷時候是關(guān)鍵字 </p><p> void retract (); //向前指針向后退一個 </p><p> void returnout (string str1,string str2); //文件打印<
18、/p><p><b> 結(jié)果及測試分析</b></p><p><b> 實驗代碼</b></p><p> /////////////////////////////////////////// 詞法分析程序@zhangjinrong///////////////////////////////////////////
19、///////</p><p> /////////頭文件////////////</p><p> #include <iostream></p><p> #include <fstream></p><p> #include <string></p><p> us
20、ing namespace std;</p><p> ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////</p><p> //關(guān)鍵字///////////</p><p>
21、 string kt[36] ={"char","short","int","unsigned","long","float","double","struct","union","void",</p><p>
22、 "enum","const","typedef","auto","static","break","case","continue","default","do","else","for",&qu
23、ot;if",</p><p> "return","switch","while","sizeof","printf","FILE","fopen","NULL",</p><p> "fclose&quo
24、t;,"exit","read","close","fprintf"};</p><p> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////<
25、/p><p> //自定義變量,數(shù)組//</p><p> ifstream infile; //以輸入(從硬盤到內(nèi)存)方式打開文件</p><p> ofstream outfile; //輸出(從內(nèi)存到硬盤)方式打開文件</p><p> char buffer1 [64];
26、 //兩個緩沖buffer </p><p> char buffer2 [64];</p><p> char C; //用于switch分析 </p><p> string token=""; //多個C組成的串 </p><p>
27、; char *startptr,*forwardptr; //buffer的開始指針和向前指針 </p><p> ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////</p><p> //函數(shù)
28、聲明//////////</p><p> void get_char (); //用于從buffer讀取一個字符到C </p><p> int letter (int C); //判斷是否是字母 </p><p> int digit (int C); //判斷時候是數(shù)字或者小數(shù)點 <
29、/p><p> int underline (int C); //判斷時候是下劃線 </p><p> int reserve (string token); //判斷時候是關(guān)鍵字 </p><p> void retract (); //向前指針向后退一個 </p><p> void ret
30、urnout (string str1,string str2); //文件打印 </p><p> ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////</p><p><b> mai
31、n ()</b></p><p><b> {</b></p><p> startptr=buffer1; //數(shù)組頭指針</p><p> forwardptr=buffer1; //數(shù)組當(dāng)前指針</p><p&
32、gt; buffer1 [63]=buffer2 [63]=-1; //數(shù)組尾數(shù)值為-1</p><p> cout<<"輸入源文件的路徑和文件名:(例: F:1.c)"<<endl;</p><p> string str111;</p><p> cin>>str111;&l
33、t;/p><p> infile.open (str111.c_str (),ios::binary);//二進(jìn)制文件</p><p> cout<<"輸入經(jīng)詞法分析后生成文件的路徑和文件名:"<<endl;</p><p> string str222;</p><p> cin>>
34、;str222;</p><p> outfile.open (str222.c_str (),ios::trunc);//再次寫入覆蓋文件已有內(nèi)容</p><p> //////////////////////////////////////////////////////////////////////////////////////////////////////////////
35、//////////</p><p> ///將文件內(nèi)容讀入第一緩沖區(qū)/////</p><p> for (int i=0;i<=62;i++)</p><p> buffer1 [i]=infile.get ();//將文件中字符放入第一緩沖區(qū)</p><p><b> while (1)</b><
36、;/p><p><b> {</b></p><p> token=""; //多個C組成的串為空</p><p> get_char (); //從數(shù)組中傳遞出一個字符c</p><p> switch (C)</p><p><b> { &
37、lt;/b></p><p> ////當(dāng)首位字符為字母////////////////////////////////////////////////////////////////////////////////////////////////////</p><p> case 'a':case 'b':case 'c':ca
38、se 'd':case 'e': case 'f': case 'g': case 'h': case 'i': case 'j':</p><p> case 'k':case 'l':case 'm':case 'n':case
39、39;o': case 'p': case 'q': case 'r': case 's': case 't':</p><p> case 'u':case 'v':case 'w':case 'x':case 'y': case 'z
40、': case 'A': case 'B': case 'C': case 'D':</p><p> case 'E':case 'F':case 'G':case 'H':case 'I':case 'J':case 'K':
41、case 'L':case 'M':case 'N':case 'O':</p><p> case 'P':case 'Q':case 'R':case 'S':case 'T':case 'U':case 'V':case '
42、W':case 'X':case 'Y':case 'Z':</p><p><b> {</b></p><p> while (letter (C)||digit (C)||underline (C)) //字母后跟字母或數(shù)字或下劃線時</p><p><b> {&l
43、t;/b></p><p> token=token+C; </p><p> get_char ();</p><p><b> }</b></p><p> if (reserve (token)==1) //如果字符串不在關(guān)鍵字表中輸出標(biāo)示符</p><p&g
44、t;<b> {</b></p><p> returnout ("關(guān)鍵字",token);</p><p><b> }else </b></p><p> returnout (token,"標(biāo)示符"); //如果在關(guān)鍵字表中輸出標(biāo)示符</p>&
45、lt;p> retract (); /*當(dāng)token已為關(guān)鍵字時由于執(zhí)行了get_char()已讀取一個字符。</p><p> 為避免漏掉需回溯一個字符*/</p><p><b> break;</b></p><p><b> }</b></p>
46、<p> ///// 當(dāng)首字母為數(shù)字時 ////////////////////////////////////////////////////////////////////////////////////////////////</p><p> case '1':case '2':case '3':case '4':case
47、39;5':case '6':case '7':case '8':case '9':case '0':</p><p><b> {</b></p><p> while (digit (C)==1||C=='.')</p><p>&l
48、t;b> {</b></p><p> token=token+C; </p><p> get_char (); </p><p><b> }</b></p><p> returnout ("常數(shù)",token);</p><p> re
49、tract ();</p><p><b> break;</b></p><p><b> }</b></p><p> //////本程序定義為運算符所以考慮不同情況////////////////////////////////////////////////////////////////////////&l
50、t;/p><p><b> case '<':</b></p><p><b> {</b></p><p> get_char (); //字符為<,<=,<>三種情況</p><p> if (C=='
51、>')</p><p> returnout ("<>","空格分界符");</p><p><b> else</b></p><p><b> {</b></p><p> retract ();</p>&
52、lt;p> returnout ("<","運算符");</p><p><b> }</b></p><p><b> break;</b></p><p><b> }</b></p><p> ////////
53、//////////////////////////////////////////////////////////////////////////////////////////////////</p><p><b> case '/':</b></p><p><b> {</b></p><p>
54、; get_char ();</p><p> if (C=='*')// 讀到/*的情況一直讀到*/結(jié)束</p><p><b> {</b></p><p><b> while (1)</b></p><p><b> {</b></p&g
55、t;<p> get_char ();</p><p> while (C!='*')</p><p> get_char ();</p><p> if (C=='/')</p><p><b> break;</b></p><p>
56、retract ();</p><p> } </p><p><b> }</b></p><p> else if (C=='/') //讀到//的情況一直讀取字符直到這一行結(jié)束</p><p><b> {<
57、;/b></p><p> get_char ();</p><p> while (C!='\n')</p><p> get_char ();</p><p> } </p><p><b> else</b></p>
58、<p><b> {</b></p><p> retract ();</p><p> returnout ("/","運算符");</p><p><b> }</b></p><p><b> break;</b&
59、gt;</p><p><b> }</b></p><p> ////////////簡單的運算符和界符//////////////////////////////////////////////////////////////////////////////</p><p> case'+' :{returnout (
60、"+","運算符");break;}</p><p> case'-' :{returnout ("-","運算符");break;}</p><p> case'*' :{returnout ("*","運算符");break;}&l
61、t;/p><p> case'=' :{returnout ("=","運算符");break;}</p><p> case'>' :{returnout (">","運算符");break;}</p><p> //case'/&
62、#39; :{returnout ("/","運算符");break;}</p><p> case'(' :{returnout ("(","界符"); break;}</p><p> case')' :{returnout (")","界符
63、"); break;}</p><p> case'[' :{returnout ("[","界符"); break;}</p><p> case']' :{returnout ("]","界符"); break;} </p>
64、<p> case';' :{returnout (";","界符"); break;}</p><p> case'.' :{returnout (".","界符"); break;}</p><p> case',' :{returnout
65、 (",","界符"); break;}</p><p> case'{' :{returnout ("{","界符"); break;}</p><p> case'}' :{returnout ("}","界符"); break;}
66、</p><p> /////////////換行和空格/////////////////////////////////////////////////////////////////////////////////////////</p><p> case ' ': break;</p><p> case '\n': c
67、ase'\r': //遇到換行符</p><p><b> {</b></p><p> if (C=='\n')</p><p><b> break;</b></p><p><b> }</b></p>
68、<p><b> default: </b></p><p><b> {</b></p><p> outfile<<"< "<<C<<" , 換行符>"<<endl;</p><p><b>
69、 break;</b></p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p> infile.close ();</p><p> outfile.clos
70、e ();</p><p> system ("pause");</p><p><b> return 0;</b></p><p><b> }</b></p><p> ////////////////////////////////////////////////
71、//////////////////////////////////////////////////////////////////////////////</p><p> /////雙緩沖的實現(xiàn)////</p><p> void get_char ()</p><p><b> {</b></p><p>
72、 if ((* forwardptr)==-1) //當(dāng)前指針在緩沖區(qū)(不知是那個緩沖區(qū))末尾</p><p><b> {</b></p><p> if (forwardptr==buffer1+63) //在第一buffer尾,向第二buffer讀入數(shù)據(jù) </p><
73、;p><b> {</b></p><p> for (int i=0;i<=62;i++)</p><p> buffer2 [i]=infile.get ();</p><p> forwardptr=buffer2;</p><p> get_char ();</p><p
74、><b> }</b></p><p> else if (forwardptr==buffer2+63) //在第二buffer尾,向第一buffer讀入數(shù)據(jù) </p><p><b> {</b></p><p> for (int i=0;i<=62;i++)</p>
75、<p> buffer1 [i]=infile.get ();</p><p> forwardptr=buffer1;</p><p> get_char ();</p><p><b> }</b></p><p> else //
76、在不是buffer尾的位置讀到了EOF,說明完成了分析 </p><p><b> {</b></p><p> infile.close ();</p><p> outfile.close ();</p><p> ofstream out;</p><p> cout<<
77、;"詞法分析結(jié)果已存入文件夾中"<<endl;</p><p> system ("pause");</p><p> exit (-1);</p><p><b> }</b></p><p><b> }</b></p>
78、<p><b> {</b></p><p> C=(*forwardptr); //當(dāng)前字符用于分析</p><p> forwardptr=forwardptr+1; //當(dāng)前指針改指向下一個字符 </p><p><b> }&
79、lt;/b></p><p><b> }</b></p><p> /////////////////////////////////////////////////////////////////////////////////////////////////////////////</p><p> ///自定義簡單函數(shù)///
80、/</p><p> int letter (int C)</p><p><b> {</b></p><p> if ((C>=65&&C<=90)||(C>=97)&&(C<=122))</p><p><b> return 1;</
81、b></p><p> else return 0;</p><p><b> }</b></p><p> int digit (int C)</p><p><b> {</b></p><p> if ((C>=48)&&(C<
82、;=57))</p><p><b> return 1;</b></p><p> else return 0;</p><p><b> }</b></p><p> int underline (int C)</p><p><b> {</b
83、></p><p> if (C=='_')</p><p><b> return 1;</b></p><p> else return 0;</p><p><b> }</b></p><p> int reserve (string
84、token)</p><p><b> {</b></p><p> for (int i=0;i<=35;i++)</p><p><b> {</b></p><p> if (token==kt [i])</p><p><b> return
85、 1;</b></p><p><b> }</b></p><p><b> return 0;</b></p><p><b> }</b></p><p> void retract ()</p><p><b>
86、{</b></p><p> if (forwardptr==buffer1) //向前指針在buffer頭</p><p> forwardptr=(buffer2+63); //后退一個字符在第二緩沖區(qū)末尾</p><p><b> else </b></p>
87、<p><b> {</b></p><p> if (forwardptr==buffer2) //使向前指針在第二個buffer尾</p><p> forwardptr=(buffer1+63);</p><p> else forwardptr--;</p><p><b
88、> }</b></p><p><b> }</b></p><p> void returnout (string str1,string str2)</p><p><b> {</b></p><p> outfile<<"< "
89、;<<str1<<" , "<<str2<<" >"<<endl;</p><p><b> }</b></p><p> ////////////////////////////////////////////////////////////////////
90、//////////////////////////////////////////////////////////////////////////YANTAN//UNIVERSITY///SC/09/1/1/2009/2550/1128/qq/1013415421///////////////////////////////////////////////////////////////////////////////////////
91、///////////////////////////////////////</p><p><b> 參考文獻(xiàn)</b></p><p> 【1】百度文庫《fseek用法詳解》</p><p> 【2】百度文庫《c和c++文件讀寫操作》</p><p> 【3】程序設(shè)計語言編譯原理》國防 陳火旺</p&g
溫馨提示
- 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. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 課程設(shè)計----編譯原理詞法分析器
- 編譯原理課程設(shè)計報告詞法分析器
- 編譯原理課程設(shè)計報告之詞法分析器
- 編譯原理詞法分析器語法分析課程設(shè)計
- 編譯原理課程設(shè)計-詞法語法分析器
- 編譯原理課程設(shè)計--pascal語言詞法、語法分析器設(shè)計
- 課程設(shè)計詞法分析器
- 編譯原理課程設(shè)計詞法分析
- 編譯原理課程設(shè)計--詞法分析
- 編譯原理課程設(shè)計--- 語法分析器
- 編譯原理課程設(shè)計---語法分析器
- 編譯原理課程設(shè)計--語法分析器
- 編譯原理語法分析器課程設(shè)計
- 編譯原理課程設(shè)計--- 詞法分析程序
- 編譯原理課程設(shè)計(c++)-語法分析器
- 編譯原理課程設(shè)計---ll(1)遞歸下降分析器
- 編譯原理課程設(shè)計--表達(dá)式語法分析器
- 編譯原理課程設(shè)計-lr分析器總控程序的實現(xiàn)
- c-minus詞法分析和語法分析設(shè)計編譯器編譯原理課程設(shè)計
- 編譯原理課程設(shè)計-ll1文法分析器設(shè)計
評論
0/150
提交評論