java編譯器源碼解析-語法分析(1)


java語法解析器的核心類是com.sun.tools.javac.parser.JavacParser,令人驚訝的是java並沒有使用antlr這樣現成的的工具,而是選擇手寫。推測可能是為了性能的考慮吧。

接下來,讓我們膜拜下大師的代碼。

JavacParser.parseCompilationUnit()是java語法分析的入口方法。

parseCompilationUnit()的返回結果是一個JCTree.JCCompilationUnit,說的更直白一點就是一顆抽象語法樹AST。

一、抽象語法樹

借用一張圖來說明JCTree以及子類的構成。

注意:每個Tree節點都有一個對應的sym屬性

 

 

當然這還不是全部,但已經可以初步看出AST的基本構成。

 

 

它的子類包括我們耳熟能詳的類聲明、變量聲明和其他if/while/for語句一樣繼承於JCStatement類。

方法聲明節點、標識符聲明節點、表達式節點都直接繼承JCTree。

一元表達式、二元表達式等繼承於表達式節點JCExpression類。

下面是JCTree及其主要子類的類圖

 

 

既然是一棵樹,那么肯定要進行變量,JCTree中專門實現了一個內部抽象類Visitor來支持對各個節點的訪問。這就用到了訪問者模式。

Visitor支持的方法如下:

 

 

二、語法分析

繼續parseCompilationUnit()的分析,代碼很多,但核心的方法是typeDeclaration(),顧名思義是做類型定義的解析。

進入新的方法,發現類型可以分為三種classOrInterfaceOrEnumDeclaration():

類解析、接口解析和枚舉類解析。

分別對應三個方法,返回值都是JCClassDecl:

JCClassDecl classDeclaration()

JCClassDecl interfaceDeclaration()

JCClassDecl enumDeclaration()

相對而言,接口和枚舉類要比類更簡單,因此我們直接去查看類定義解析的內容。

類解析從解析類的泛型參數開始,具體內容在typeParametersOpt()中。

如果有extend或者implement就會去解析父類和接口。這里的邏輯不復雜,我們就不展開了。

類的body是比較復雜的,源碼中專門寫了一個方法classOrInterfaceBody()實現它。

classOrInterfaceBody具體實現classOrInterfaceBodyDeclaration方法中。

類的定義中可以繼續定義類,所以

1.首先判斷是不是內部類

2.然后如果是一個“{”,那就進行block的解析

3.最后就是變量的聲明variableDeclaratorsRest()和方法的聲明methodDeclaratorRest()

三、變量聲明

變量聲明的解析又分普通變量的聲明和array的聲明,是區分對待的。

不可避免的,變量聲明的右邊是一個表達式parseExpression()

四、方法定義

methodDeclaratorRest()

方法定義首先解析方法的參數params,之后今日block()方法。

block()由一系列blockStatements()組成。進而調用blockStatement(),blockStatement()有多種語句,比如:

parseStatement()解析一般的Statement

classOrInterfaceOrEnumDeclaration()解析類

variableDeclarators()解析變量聲明

再加上解析表達式的parseExpression()。所有語法解析的核心邏輯就在這幾個方法中


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM