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

来源:https://www.cnblogs.com/chenqiwei/archive/2019/07/13/RunWsh_word001.html
-Advertisement-
Play Games

編譯原理課程設計詞法分析任務書 5)參考文獻: (1)張素琴,呂映芝. 編譯原理[M]., 清華大學出版社 (2)蔣立源、康慕寧等,編譯原理(第2版)[M],西安:西北工業大學出版社 6)課程設計進度安排 1.準備階段(4學時):選擇設計題目、瞭解設計目的要求、查閱相關資料 2.程式模塊設計分析階段 ...


 

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

 

 

5)參考文獻:

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

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

6)課程設計進度安排

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

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.2、任務與要求

  【基本要求】

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

【測試數據】

如源程式為C語言。輸入如下一段:

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

 

測試數據

 

 12,”main”)    (2,”a”)
 2 
 35,”(“)      (4,”=”)
 4 
 55,”)“)      (3,”10”)
 6 
 75,”{“)       (5,”;”)
 8 
 91,”int”)     (2,”b”)
10 
112,”a”)       (4,”=”)
12 
135,”,”)       (2,”a”)
14 
152,”b”)       (4,”+”)
16 
175,”;”)       (3,”20”)

 

 

 

二、需求分析

2.1、分析

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

 

2.2、問題解決

  對讀取的文件進行預處理,從頭到尾進行掃描,去除//和/*  */的內容,以及一些無用的、影響程式執行的符號如換行符、回車符、製表符等。但是千萬註意不要在這個時候去除空格,因為空格在詞法分析中有用,比如說int i=3;這個語句,如果去除空格就變成了“inti=3”,這樣就失去了程式的本意,因此不能在這個時候去除空格。

 

2.3、解決步驟

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

 

 

 

 

三、設計思路

3.1、總體思路分析

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

 

狀態圖

 

 

 

 

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

總控程式流程圖:

 

 

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

3.2、設計原理

主要任務如下:

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

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

圖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.1、項目設計步驟

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++){//是否為關鍵字,,是返回1
    2                      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'){//第一個是否為數字返回3
34                             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:語言單詞編碼

 

五、運行調試與分析討論

程式運行環境為Win10系統,在IDEA/ECLIPSE上運行

運行結果分析如下:

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

 

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

 

 

 

 

 

 

 

 

 

5.2輸出異常處理:

 

a)        文件路徑異常

 

 

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

 

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

 

 

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

六、設計體會與小結

 

心得體會:

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

 

學習心得:

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

 

七、參考文獻

 1 [1] 張素琴.編譯原理. 北京:清華大學出版社,2005
 2 
 3 [2] 付京周.JAVA 程式設計語言. 北京:人民郵電出版社,2007
 4 
 5 [3]黃賢英,王珂珂.編譯原理及實踐教程.北京:清華大學出版社,2008
 6 
 7 [4]黃賢英,王珂珂,劉潔,曹瓊.編譯原理重點難點分析.習題解析·實驗指導.北京:機械
 8 
 9 工業出版社,2008
10 
11 [5]陳媛,何波,塗曉紅,塗飛演算法與數據結構.北京:清華大學出版社,2005[4]劉恆洋,楊巨集雨.演算法與數據結構.北京:機械工業出版社,2010
12 
13 [6]陳火旺,《程式設計語言編譯原理》(第3版),北京:國防工業出版社.2000.
14 
15 [7]美Alfred V. Aho Ravi Sethi Jeffrey D. Ullman著.李建中,薑守旭譯.《編譯原理》. 北京:機械工業出版社.2003.
16 
17 [8]美KennethC. Louden著.馮博琴等譯.《編譯原理及實踐》.北京:機械工業出版社.2002.
18 
19 [9]金成植著.《編譯程式構造原理和實現技術》.北京:高等教育出版社.2002.

 

 

掃碼公眾號--回覆“詞法分析”獲取源碼:

 

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、子元素選擇器 1. (1)選中標簽之中只有一個子元素的子元素,並且那個標簽必須使我們格式中前面指定的標簽才行 (2)格式: (3)舉例: 2. (1)同級別中我們指定的標簽中,只有這種類型一個的元素來指定格式 (2)格式 (3)舉例 3. (1)定義:同級別中所有標簽中規則的且為指定標簽的設置屬 ...
  • BOM BOM ECMAScript是JavaScript的核心,但如果要在Web中使用JavaScript,那麼BOM(瀏覽器對象模型)則無疑才是真正的核心,BOM提供了很多對象,用於訪問瀏覽器的功能,這些功能與任何網頁內容無關,那麼,什麼是BOM呢?我們可以從這幾點解析一下: 1.BOM是Bro ...
  • 實現思路 獲取input的file 使用fileReader() 將圖片轉為base64 使用canvas讀取base64 並降低解析度 把canvas數據轉成blob對象 把blob對象轉file對象 完成壓縮 相關代碼: 最後回調函數中的files可以直接當做正常的input file 使用,如 ...
  • 裝飾器是什麼? 解碼器是將另一段代碼包裝在一個代碼中的簡單方法。 這個概念類似於你以前聽說過的功能成分和高階成分。 這在許多情況下都被使用過,也就是說,成都裝修公司簡單地將一個函數包裝到另一個函數中: 前面的示例生成包裝的新函數,它執行與 DoSomething 相同的操作,但它們的不同之處在於在包 ...
  • HTML代碼: js代碼: ...
  • 可以使用 window.location 獲取當前頁面url。以下是一些簡單應用。 ...
  • html代碼: js代碼: ...
  • 史上最全的,web前端零基礎,系統學習路線圖!學好web前端,前途寬廣!如今隨著“互聯網+”上升到國家戰略,軟體行業與國民經濟關係密,幾乎絕大多數行業的發展都會促進軟體行業的發展。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...