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

javac編譯原理

每個人在學習Java的時候都配置過環境變數,檢查是否配置成功的時候,我們總會在命令列敲入兩個命令,一個是 java,一個是 javac。剛開始我們都不知道這兩個命令代表的含義,隨著學習的深入,我們知道了 java 命令就是檢查是否找得到執行環境,而 javac 就是編譯Java原始碼的編譯器。現在,深入探索一下 javac 這個神奇的編譯器,看看它的背後到底是什麼。

javac的流程

 javac是一種編譯器,能夠將一種語言規範轉化成另一種語言規範。javac的任務是將Java原始碼語言轉化成JVM能夠識別的語言,然後由JVM將JVM語言再轉化成當前機器能夠識別的機器語言。Java語言向開發者遮蔽了很多與目標機器相關的細節,使得Java語言的執行與平臺無關。

 如下圖所示,javac的任務就是將Java原始碼編譯成Java位元組碼(二進位制流),也就是JVM能夠識別的語言:

image

 要清楚javac編譯器有哪些工作模組或者基本結構,首先要知道其工作流程,通過工作流程去剖析細節。下面javac的工作流程圖:

image

  • 第一步,詞法分析:按位元組讀取原始碼,找出這些位元組碼檔案中我們定義的語法關鍵詞。例如:if,else,for,while等關鍵詞。識別出哪些if是合法的,哪些不是。

    通過詞法分析,從原始碼中找出了一些規範化的Token流。例如:找出一個句子裡面的標點,主語,謂語,賓語,動詞等等。

  • 第二步,語法分析:現在要做的就是對Token流做語法分析,檢查這些關鍵詞組合在一起是不是符合Java語言規範,如for迴圈格式是否正確等。

    通過語法分析形成了一個符合Java語言規範的抽象語法樹。抽象語法樹是一個結構化的語法表達形式,它的作用是把語言的主要詞法用一個結構化的形式組織在一起。例如:離散數學中用數字來表達一些有複雜關係的物質世界,圖,樹等。

  • 第三步,語義分析:語義分析的主要工作是把一些難懂的,複雜的語法轉化成更加簡單的語法。例如:將難懂的文言文轉化成易懂的白話文。

    語義分析的結果是將複雜的語法轉化成最簡單的語法,例如:將lambda表示式轉成簡單的資料結構,並加上註解。最後形成一個註解過後的抽象語法樹,該語法樹更接近目標語言的語法規則。

  • 第四步,程式碼生成器生成位元組碼:根據經過註解的抽象語法樹生成位元組碼,也就是將一個數據結構轉化成另一個數據結構。例如:將白話中文翻譯成英文。

 javac的各個模組完成了將Java原始碼轉化成Java位元組碼的任務,所以javac主要有四個模組:詞法分析器,語法分析器,語義分析器,程式碼生成器。

JDK中rt.jar、tools.jar和dt.jar作用
  • rt.jar 是Java基礎類庫,位於/jre/lib目錄下,由應用程式類載入器(Application ClassLoader)載入:

image

  • dt.jar是關於執行環境的類庫,位於/lib目錄下,由啟動類載入器(Bootstrap Classloader)載入:

  • tools.jar是工具類庫,編譯和執行需要的都是toos.jar裡面的類分別是sun.tools.java.; sun.tols.javac.,位於/jre/lib目錄下,由啟動類載入器(Bootstrap Classloader)載入:

image