2015-09-25 35 views
7

我一直致力於從8年以上的JavaJava編譯器的內部架構

上週,在我公司的一次小型會議上,我的一位同事問我Java Compiler的工作原理是什麼?我沒有回答。

我試着解釋,像Java編譯器一個接一個的語句,並將它們轉換爲字節碼,它不是針對任何OS,而是針對JVM

即使我沒有人滿意答案。

現在的主要問題是java編譯器的工作原理。即在編譯Java文件的情況下編譯器將完成多少個步驟或階段或階段。

究竟是什麼Java's compiler架構?

如果在同一個.java文件中有多個Java classes會怎麼樣。那麼將編譯多少個類。

如果有導入指向未編譯的Java類,該怎麼辦?那麼未編譯的類會被編譯或忽略?

我搜索了超過半天的時間,所有答案都和我給同事一樣。

但最後我發現了一些有用的教程here

但該教程也涵蓋不太深入,我無法想象該教程。

儘管如此,我還是不滿意,並且渴望從你那裏瞭解更多關於此的內容。

因此,如果任何人知道比我和上述博客更多的東西,通過使用我可以直觀地看到Java Compiler的內部架構請解釋我。

+0

JVM規範相當詳細:https://docs.oracle.com/javase/specs/jvms/se8/html/index.html –

+0

[java編譯如何發生](http:// stackoverflow。 COM /問題/ 3406942 /如何-恰好做Java的編譯通吃的地方)。 – YoungHobbit

+0

[Java虛擬機](https://www.artima.com/insidejvm/ed2/jvmP.html)。 – YoungHobbit

回答

7

一些基本步驟:

  1. 解析:讀取一組* .java源文件和地圖生成的令牌 序列爲AST(抽象語法樹)-nodes。
  2. enter:在符號表中輸入定義符號。
  3. 流程註釋:如果請求,處理在 中找到的指定編譯單元中的註釋。
  4. 屬性:屬性語法樹。該步驟包括名稱 分辨率,類型檢查和常量摺疊。
  5. flow:對上一步的樹進行數據流分析。 這包括檢查分配和可達性。
  6. desugar:重寫AST並翻譯一些語法糖。
  7. generate:生成源文件或類文件。

在更多的細節:

  1. 萊克斯 - 打破源文件爲單個單詞,或代幣。
  2. 解析 - 分析程序的短語結構。
  3. 語義操作 - 構建與每個短語對應的抽象語法樹。
  4. 語義分析 - 確定每個短語的含義,將變量的使用與其定義相關聯,檢查表達式的類型,請求翻譯每個短語。
  5. 框架佈局 - 將變量,函數參數等以與機器相關的方式放入激活記錄(堆棧框架)中。
  6. 翻譯 - 生成中間表示樹(IR樹),與任何特定源語言或目標機器體系結構無關的符號 。
  7. Canonicalize - 提升表達式的副作用,並清理條件分支,以方便下一階段。
  8. 指令選擇 - 將IR-tree節點分組爲與目標機器指令的動作相對應的塊。
  9. 控制流分析 - 將指令序列分析成控制流程圖,顯示程序在執行時可能遵循的所有可能的控制流程。

  10. 數據流分析 - 通過程序的變量收集有關信息流的信息;例如,活性分析計算每個程序變量保持仍然需要的值(即實時)的位置。

  11. 寄存器分配 - 選擇一個寄存器來保存程序使用的每個變量和臨時值;變量不能同時生活 可以共享相同的寄存器。

  12. 代碼發射 - 用每個機器指令中的臨時名稱替換爲 機器寄存器。

有一個很好的書:在Java中

現代編譯器實現

你可能想看看javac的代碼中:

Javac Documentation

OpenJDK source code

Hacker's guide to javac

Don't Panic! To help newcomers to javac navigate their way around the code base

JVM JLS

+0

請包括您已包含和刪除的PDF文件網站地址。 – Jagadeesh

+0

我把它放回去了。謝謝 – ACV

6

上有一個編譯器不同的步驟,但在這裏是最重要的:

詞法分析 第一步是詞法分析。基本上這個步驟從Java代碼提取令牌(關鍵字,運算符,分離器,註釋,變量名...)

語法分析(解析器) 第二步是語法分析。令牌被作爲詞法分析的輸入,並被組合成表達式和指令。

優化和轉換爲字節碼 最後一個宏步驟是將上一步轉換爲字節碼。這裏的代碼可以修改爲等效於原始代碼,但效率更高。


注:這個過程是不是隻涉及到Java,但它適用於所有的編譯器。還有不會產生中間字節代碼而是機器代碼的編譯器(比如C或C++的編譯器)。

通常有工具可以創建詞法分析器和語法分析器,因爲這些步驟在不同語言之間有許多公共部分。

一個開放源碼的詞彙analizer是flex 一個有用的語法analizer是yacc

兩個可與C和C++是最常用的語言創建編譯器(java和別人太),但也有類似的替代品對於其他編程語言(創建編譯器另一種語言,而不是對於另一種語言)。基本上編寫編譯器的語言與編譯器編譯的語言無關。