1. 程式人生 > >Javac 編譯原理

Javac 編譯原理

技術 width 開發 pan 安裝 spa 判斷 開發者 開發環境

寫在前面 JDK & JRE

JRE(Java Runtime Enviroment)是Java的運行環境。面向Java程序的使用者,而不是開發者。如果你僅下載並安裝了JRE,那麽你的系統只能運行Java程序。JRE是運行Java程序所必須環境的集合,包含JVM標準實現及 Java核心類庫。它包括Java虛擬機、Java平臺核心類和支持文件。它不包含開發工具(編譯器、調試器等)。


JDK(Java Development Kit)又稱J2SDK(Java2 Software Development Kit),是Java開發工具包,它提供了Java的開發環境(提供了編譯器javac等工具,用於將java文件編譯為class文件)和運行環境(提 供了JVM和Runtime輔助包,用於解析class文件使其得到運行)。如果你下載並安裝了JDK,那麽你不僅可以開發Java程序,也同時擁有了運行Java程序的平臺。JDK是整個Java的核心,包括了Java運行環境(JRE),一堆Java工具tools.jar和Java標準類庫 (rt.jar)。

JDK also could be called as SDK(Software Development Kit) for Java.


1.Javac是什麽?

Javac是一種編譯器,能將一種語言規範轉化為另外一種語言規範通常編譯器都是將便於人理解的語言規範轉化成機器容易理解的語言規範

Javac的任務就是將java源碼編譯成java字節碼,也就是JVM能夠識別的二進制碼。表面上來看就是將.java文件轉化為.class文件,實際上是將java的源代碼轉化成一連串有格式的二進制數字,只有JVM能夠正確識別它們到底表達了什麽意思。

2.Javac的工作流程及類比

  2.1 尋找語法關鍵詞 比如if else for while 等,這個過程稱為詞法分析

(詞法分析的結果是從源代碼中找出一些規範化的Token流

  類比:人類語言中分辨 詞語 標點符號 動詞 名詞

  2.2 檢查這些關鍵詞組合在一起是否符合Java語言規範,這個過程稱為語法分析 (語法分析的結果是一個符合Java規範的抽象語法樹

  類比: 人類語言中是不是有主謂賓 主謂賓組合的是否正確 語法是否正確

  2.3 將難懂的、復雜的語法轉化為更加簡單的語法,這個過程稱為語義分析 (比如說將foreach轉成for,結果是生成了一個註解過後的抽象語法樹,這棵樹更加接近目標語言的語法規則)

  類比:人類語言中將難懂的文言文翻譯為白話文

  2.4 通過字節碼生成器生成字節碼,將經過註解的抽象語法樹生成字節碼

,也就是將一個數據結構轉化為另一個數據結構

  類比:將中文詞語翻譯為英文單詞後,按照英文語法組裝成英文語句

  綜上所述,Javac主要有四個模塊,分別是詞法分析器、語法分析器、語義分析器和代碼生成器。

3.詞法分析器

1 package compile;
2 
3 public class Cifa {
4   int a;
5   int c = a+1;
6 }      

詞法分析器的分析結果就是將這個類中的所有關鍵詞匹配到token類的所有項中的任何一項。上述代碼的匹配結果如下圖

技術分享

4.語法分析器

詞法分析器的作用是將Java源文件的字符流轉變成對應的Token流,而語法分析器是將Token流組建成更加結構化的語法樹,也就是將一個個單詞組裝成一句話。

 1 public class Yufa{
 2   int a;
 3   private int c =a +1;
 4   
 5   public int getC(){
 6       return c;
 7   }
 8 
 9   public void setC(int c){
10      this.c = c;
11   }
12 }

這段代碼對應的語法樹

技術分享

5.語義分析器

經過語法分析器生成的語法樹過於粗糙,此時需要在這顆語法樹的基礎上再做一些處理,比如給類添加構造函數、檢查變量在使用前是否初始化、將一些常量進行合並處理,檢查操作變量類型是否匹配,檢查所有的操作語句是否可達,檢查checked exception異常是否已經捕獲或拋出,接觸Java語法糖(泛型,裝拆包),去除一些永不為真的條件判斷,內部類會被分離出去但是持有一個外部類的引用

6.代碼生成器

將Java方法中的代碼塊轉化成符合JVM語法的命令形式,JVM的操作都是基於棧的,所有的操作都必須經過出棧和進棧來完成。

按照JVM的文件組織格式將字節碼輸出到以class為擴展名的文件中

Javac 編譯原理