天天看點

java實作文法分析器_文法分析 | 文法分析的任務

在之前,我們有對編譯器做過一定的介紹,我們認為編譯器是具有一定流水線結構的軟體系統。它可以分為前端,中端和後端這樣的不同的階段。

java實作文法分析器_文法分析 | 文法分析的任務

編譯器前端

對于我們正在研究的前端,我們已經通過詞法分析的學習掌握了從将源程式轉化為記号流的過程。

對于之後的文法分析器階段,我們在編譯器設計的早期,隻實作了分析源程式是否合法,如果不合法就傳回程式的出錯資訊給程式員,退出源程式的編譯過程。程式員對代碼進行修改後就重新開機該編譯過程,重新進行詞法分析和文法分析...。在後期的編譯器設計過程中,我們的文法分析過程就通常需要生成一個抽象文法樹的中間表示。該文法書輸出到後續階段,用于語義分析器或者代碼生成器進行進一步的處理。這樣的新設計使文法分析器能夠更加專注于自己的任務,将語義檢測和代碼生成的任務交給後續階段再來進行處理。

文法分析器是前端比較核心的子產品,負責處理程式員輸入的程式,産生編譯器後端需要使用的第一個非常核心的資料結構——抽象文法樹。

單獨提出文法分析器的子產品如下,輸入是記号流,輸出是文法書。

java實作文法分析器_文法分析 | 文法分析的任務

文法分析器是以語言的文法規則為準則對從記号流輸入的文法進行分析的。

舉個文法錯誤處理的例子:

java實作文法分析器_文法分析 | 文法分析的任務

對于上面的程式,如果進行文法分析,可以得到如下的文法錯誤:

java實作文法分析器_文法分析 | 文法分析的任務
  • 第一行缺少右圓括号,
  • 第二行缺少分号
  • 第四行,得到了一個逗号而不是期待得到的分号

在舉一個文法書的建構的例子

如果程式員根據上面得到的回報資訊對源代碼進行修改,使其能夠得到一個可以通過文法分析器的代碼,該代碼顯示如下:

java實作文法分析器_文法分析 | 文法分析的任務

文法分析會接着對文法分析通過的代碼存入記憶體,由于對如此顯示的字元串的存儲後續的處理會過于麻煩,是以我們需要對其構造一定的資料結構,我們通常選用文法樹的資料結構。文法樹顯示如下:

java實作文法分析器_文法分析 | 文法分析的任務

對這樣的一個代碼分析完成後,我們傳回的是該樹的根節點的指針。

文法分析是編譯器中第一個做切分的階段,将程式員所寫的字元串變化到相應的樹狀結構上。

文法分析的路線圖

  • 數學理論:上下文無關文法(CFG)
    • 描述語言文法規則的數學工具
  • 自頂向下分析
    • 遞歸下降分析算法(預測分析算法)
    • LL 分析算法
  • 自底向上分析
    • LR 分析算法

原文連結:

  • 編譯原理 - 網易雲課堂