編譯原理課程設計詞法分析

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

 

編譯原理課程設計詞法分析任務書正則表達式

 

 

5)參考文獻:算法

(1)張素琴,呂映芝. 編譯原理[M]., 清華大學出版社編程

(2)蔣立源、康慕寧等,編譯原理(第2版)[M],西安:西北工業大學出版社數組

6)課程設計進度安排數據結構

1.準備階段(4學時):選擇設計題目、瞭解設計目的要求、查閱相關資料ide

2.程序模塊設計分析階段(4學時):程序整體設計、詳細設計函數

3.代碼編寫調試階段(8學時):程序模塊代碼編寫、調試、測試工具

4.撰寫論文階段(4學時):總結課程設計任務和設計內容,撰寫課程設計論文性能

 

  學生簽名:              學習

      2019 年   5  月  9  日

 

課程設計(論文)評審意見

(1)學習態度(20分):優( )、良( )、中( )、通常( )、差( );

(2)系統設計(20分):優(  )、良( )、中( )、通常( )、差( );

(3)編程調試(20分):優( )、良( )、中( )、通常( )、差( );

(4)回答問題(20分):優( )、良( )、中( )、通常( )、差( );

(5)論文撰寫(20分):優( )、良( )、中( )、通常( )、差( );

 

評閱人:            職稱:  講師      

2019  年  5  月 10  日

 

 

中文摘要

實現功能及實現:

  主要實現對文本中的程序進行詞法分析,把程序中的單詞分爲五大類(基本保留字[1]、標識符[2]、常數[3]、運算符[4]、分隔符[5])並與相應的區域數字來對應輸出.

  以前利用Java中的BufferedReader緩衝器對象來存儲讀取程序的文件,在劉立月老師指導下,較大程序文件的時有超時的狀況,後更改爲一行編譯讀取方式.利用兩個異常處理,文件讀取異常和輸出異常時打印ERROR.

 

背景和意義:

  詞法分析的過程是線性的從頭到尾掃描一遍,複雜度較低,易實現。能完成計算機翻譯過程的關鍵階段,它爲後面的語法分析、語義分析作好準備,打好基礎,以便快速地、高質量地生成目標語言程序。

 

 

關鍵字: 詞法分析、文件異常、目標語言程序

 

 


 

 

1、課程設計任務及要求

1.一、目的

  經過使用一個通用的可以自動根據正規表達式生成詞法分析程序的工具程序設計一個簡單語言的詞法分析器,使學生充分理解課程理論內容和工具軟件的使用技巧,掌握所涉及的典型數據結構,算法及方法,爲從此在大型軟件系統實踐中設計性能優良的軟件系統打下基礎。

1.二、任務與要求

  【基本要求】

   編制一個讀單詞過程,從輸入的源程序中,識別出各個具備獨立意義的單詞,即基本保留字、標識符、常數、運算符、分隔符五大類。並依次輸            出各個單詞的內部編碼及單詞符號自身值。(遇到錯誤時可顯示「Error」,而後跳過錯誤部分繼續顯示)

【測試數據】

如源程序爲C語言。輸入以下一段:

1 main(){2 3 int  a,b;4 5 a = 10;6 7      b = a + 20;8 9 }

 

測試數據

 

 1 (2,」main」)    (2,」a」) 2  3 (5,」(「)      (4,」=」) 4  5 (5,」)「)      (3,」10」) 6  7 (5,」{「)       (5,」;」) 8  9 (1,」int」)     (2,」b」)10 11 (2,」a」)       (4,」=」)12 13 (5,」,」)       (2,」a」)14 15 (2,」b」)       (4,」+」)16 17 (5,」;」)       (3,」20」)

 

 

 

2、需求分析

2.一、分析

  經過修改代碼使得自動機可以更多的實現運算符號的識別功能,使用TINY語言調試一個程序,加深同窗對詞法分析的認識以及理解。另外,同時加強編寫和調試程序的能力。

 

2.二、問題解決

  對讀取的文件進行預處理,從頭至尾進行掃描,去除//和/*  */的內容,以及一些無用的、影響程序執行的符號如換行符、回車符、製表符等。可是千萬注意不要在這個時候去除空格,由於空格在詞法分析中有用,好比說int i=3;這個語句,若是去除空格就變成了「inti=3」,這樣就失去了程序的本意,所以不能在這個時候去除空格。

 

2.三、解決步驟

  對源文件從頭至尾進行掃描了,從頭開始掃描,主控程序主要負責系統創建一個文件保存四個表,這四個表分別存儲關鍵字、運算符、界符、過濾符。而標識符和常數則用正則表達式判斷。創建了多個布爾類,當系統讀取代碼時,用空格或製表符做爲標誌符,當遇到空格就輸出以前檢索的字符串進行判斷(規定每一個單詞符號之間都有空格),判斷字符串時,系統會經過順序查找依次調用布爾類與之匹配來判斷其屬性並輸出,如沒有匹配成功,則說明所檢索的字符串不合法,系統則會輸出非法字符串。直到最後一個字符串匹配完畢以後系統結束。

 

 

 

 

3、設計思路

3.一、整體思路分析

  程序的關鍵點在於對給出一段程序中的各類單詞的分離。在每段程序中,單詞種類能夠分爲:關鍵字,分界符,算術運算符,關係運算符,標識符和常數。關鍵字的判斷則是經過與已知數組中列出的元素進行對比,得出該單詞是否爲關鍵字;分解符,算術運算符,關係運算符的判斷與接受到的字符進行比較,得出該字符是否爲分解符,算術運算符或者爲關係運算符。

 

狀態圖

 

 

 

 

圖3-1-1:功能模塊分解圖

總控程序流程圖:

 

 

圖3-1-2:控制流程圖

3.二、設計原理

主要任務以下:

識別出輸入的源程序中的單詞,輸出二元組形式的單詞序列。

刪除無用的空白字符、回車符等沒有實質意義的字符。

圖3-2:正規式和狀態轉換圖

實驗步驟:

PL/0語言文法的EBNF表示以下:

 

 1 <程序>::=begin<語句串>end 2  3   4  5 <語句串>::=<語句>{;<語句>} 6  7 <語句>::=<賦值語句> 8  9  10 11 <賦值語句>::=ID:=<表達式>12 13  14 15 <表達式>::=<項>{+<項> | -<項>}16 17  18 19 <項>::=<因子>{*<因子> | /<因子>20 21  22 23 <因子>::=ID | NUM | (<表達式>)

 

 

 

3.3實現方法

本次實驗是設計詞法分析器,其中核心函數是cifa(),分析的語言是PL/0,首先,採用循環遍歷的方法讀取用戶輸入的一段代碼,跳過源程序中的空格字符,而後if語句配合switch語句對讀入的代碼挨個判斷,最後以二元組的形式輸出結果。

 

 

 

 

 

 

 

 

4、詳細設計

4.一、項目設計步驟

a)        建立存放識別程序文件

 

 

圖4-1:待編譯程序文件test.txt

 

b)       讀取文件單詞並存儲

讀取文件test.txt文件:

       1 br = new BufferedReader(new FileReader("tests.txt")); 

 

存放構成單詞符號的字符串:

 1 public StringBuffer strToken = new StringBuffer(); 

 

基本保留字(關鍵字)

 1 public String [] retainWord = new String[]{"int","if","else","return","main","void","while","break"}; 

 

c)        識別不一樣程序單詞

 

基本保留字

  • 1 for(int i = 0;i < retainWord.length;i++){//是否爲關鍵字,,是返回12                      if(strToken.toString().equals(retainWord[i])){3 4                             return 1;5 6                      }7 8 }

     

 

  • 1 if(code == 1){//關鍵字2                      System.out.println("('"+1+"','"+strToken+"')");3 4               }

     

標識符

 1 for(int i = 0;i < retainWord.length;i++){//是否爲關鍵字,,是返回1 2                      if(strToken.toString().equals(retainWord[i])){ 3  4                             return 1; 5  6                      } 7  8               } 9 10               if(strToken.length() != 0){11 12                      ......13 14               }15 16               return 2;17 18        }19 20  21 22 else if(code == 2){//非數字,關鍵字23                      System.out.println("('"+2+"','"+strToken+"')");24 25               }26 27  28 29  30 31 常數32 33 if(strToken.charAt(0)>='0' && strToken.charAt(0)<='9'){//第一個是否爲數字返回334                             return 3;35 36                      }37 38  39 40 else if(code == 3){//數字41                      System.out.println("('"+3+"','"+strToken+"')");42 43               }

 

 

運算符

 1 else if(ch == 43){ 2 Retract();                
 3  4 System.out.println("('"+4+"','"+(char) ch+"')");     
 5  6                          7  8 }else if(ch == 45){                                
 9 Retract();                              
10 11 System.out.println("('"+4+"','"+(char) ch+"')");     
12 13                         14 15 }else if(ch == 42){                                
16 Retract();                              
17 18 System.out.println("('"+4+"','"+(char) ch+"')");     
19 20                         21 22 }else if(ch == 47){                                
23 Retract();                              
24 25 System.out.println("('"+4+"','"+(char) ch+"')");

 

                           

分隔符

 1 System.out.println("('"+5+"','"+(char) ch+"')"); 2        }else if((char) ch == '('){                      
 3  4               Retract();                          
 5  6 System.out.println("('"+5+"','"+(char) ch+"')");                      
 7        }else if((char) ch == ')'){                      
 8  9               Retract();                   
10 11       12 13 System.out.println("('"+5+"','"+(char) ch+"')");                      
14        }else if((char) ch == '{'){                      
15 16               Retract();            
17 18              19 20 System.out.println("('"+5+"','"+(char) ch+"')");                      
21        }else if((char) ch == '}'){                      
22 23               Retract();                   
24 25       26 27 System.out.println("('"+5+"','"+(char) ch+"')");                      
28        }else if((char) ch == ','){

 

             

d)       語言單詞編碼

 

表4-4:語言單詞編碼

 

5、運行調試與分析討論

程序運行環境爲Win10系統,在IDEA/ECLIPSE上運行

運行結果分析以下:

5.一、當在文本文件test.txt中輸入文法:

 

圖5-1-1:類型號和單詞輸出結果

 

 

 

 

 

 

 

 

 

5.2輸出異常處理:

 

a)        文件路徑異常

 

 

圖5-1-2:獲取程序文件異常

 

b)       程序中未識別單詞異常

 

 

圖5-1-3:不能識別程序單詞報錯

6、設計體會與小結

 

心得體會:

這個程序實現了課設的全部要求(因爲我是31號作第一題詞法分析模擬,但同時實現了擴展功能對於註釋的文字進行忽視編譯),雖然可能還存在些不足,像以前劉立月老師提出的個人程序對於簡短的程序是徹底能夠的,個人讀取方式是對象所有讀取.可是對於一些比較大的項目來進行對象讀取時間比較長.因而在個人程序當中進行了必定量的修改,更改爲行的讀取.用編譯原理的知識本身獨立完成這樣一個程序我以爲還不錯了,畢竟作這樣的課設能夠學到很多東西.

 

學習心得:

  一開始對編寫詞法分析毫無頭緒,不知如何下手。上網查資料是咱們邁開的第一步,而後查閱相關資料,小組裏相互討論幫助,在屢次的調試和改進中終於把程序完成了。經過此次的程序實驗我對編譯原理這門課程有了進一步的深層次瞭解,並且在自已動手體驗的狀況下,更加透徹地理解了詞法分析的過程。在設計過程當中,要發揚團體合做的精神,互幫互助,共同進步。善於發問,善於思考。