看到一篇清晰介紹AST的文章,轉載記錄下。java
將.java源文件編譯成.class文件,這一步大體能夠分爲3個過程:jvm
經過詞法分析器分析源文件中的全部字符,將全部的單詞或字符都轉化成符合規範的Token,規範化的token能夠分紅一下三種類型:spa
int x=y+1;
複製代碼
這一行代碼解析成token流以下: 3d
抽象語法樹(Abstract Syntax Tree)是一種用來描述程序代碼語法結構的樹形表示方式,語法樹的每個節點都表明着程序代碼中的一個語法結構, 如包、類型、修飾符、運算符、接口、返回值均可以是一個語法結構。code
package com.example.adams.astdemo;
public class TestClass {
int x = 0;
int y = 1;
public int testMethod(){
int z = x + y;
return z;
}
}
複製代碼
對應的抽象語法樹以下: cdn
符號表是由一組符號地址和符號信息構成的表格;符號表中所登記的信息在編譯的不一樣階段都要用到,在語法分析中, 符號表所登記的內容將用於語義檢查和產生中間代碼。在目標代碼生成階段, 符號表是當對符號名進行地址分配時的依據。blog
在JDK 1.5以後,Java語言提供了對註解(Annotation)的支持,註解與普通的Java關鍵字同樣,而在JDK 1.6中實現了JSR-269規範JSR-269:Pluggable Annotations Processing API(插入式註解處理API)。提供了一組插入式註解處理器的標準API在編譯期間對註解進行處理;在註解處理期間,咱們能夠獲取到全部的抽象語法樹,能夠對抽象語法樹進行增刪改查;語法樹被修改過以後,編譯器將回到解析及填充符號表的過程從新處理,直到全部插入式註解處理器都沒有再對語法樹進行修改成止。繼承
語義分析的主要任務是對結構正確的源程序進行上下文有關性質的審查,過程分爲標註檢查和數據及控制流分析兩個步驟:token
檢查語義合法性、進行邏輯判斷,如變量使用前是否已被聲明、變量與賦值之間的數據類型是否可以匹配等;接口
在Javac的源碼中,數據及控制流分析的入口是圖中的flow(),由com.sun.tools.javac.comp.Flow類來完成,做用是對程序上下文邏輯更進一步的驗證,檢查局部變量在使用前是否有賦值、方法的每條路徑是否都有返回值、是否全部的受查異常都被正確處理了等問題。
語法糖(Syntactic Sugar),也稱糖衣語法,指在計算機語言中添加的某種語法,Java中最經常使用的語法糖主要是的泛型擦除、變長參數、自動裝箱/拆箱、條件編譯等,解語法糖就是還原回簡單的基礎語法結構。
字節碼生成是Javac編譯過程的最後一個階段,由com.sun.tools.javac.jvm.Gen類來完成;把前面各個步驟所生成的信息(語法樹、符號表)轉化成字節碼,再將字節碼輸出到*.class文件中。
經過javac的編譯原理能夠得出: