要想自己設計并實作一個代碼自動分析、優化和重構工具,得先了解代碼;要想了解代碼,得先用一個好的資料結構來存儲和表示所讀取的代碼。基于程式代碼本身的層次結構,用樹狀結構來表示是再好不過的了,
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiYWan5SZslWbz9CX0xWdhZWZk9CX09Wbl9lcvRXakVGa49CXy9GdpRWZoh3LcRXZu5ibkN3Yuc2bsJmLjlGdhR3cvw1LcpDc0RHaiojIsJye.gif)
。
抽象文法樹(Abstract Syntax Tree, AST)使用樹狀結構來表示源代碼的抽象文法結構,樹上的每一個節點都對應源代碼中的一種結構,它作為程式代碼的一種中間表示形式,在代碼分析、代碼重構、語言翻譯等領域得到廣泛的應用。現有的一些相關工具中,都會存在自行将源代碼轉換為抽象文法樹的子產品。至于将哪些文法節點進行轉換,不同的工具會有不同的定義。
在圖1中,對于Java程式中一個for循環片段,使用抽象文法樹進行簡單的轉換/分解,以便于大家可以簡單直覺地感受到抽象文法樹中所展示的字、詞、句、段、篇,圖1的分解所依據的是Eclipse JDT中Eclipse AST對抽象文法樹的定義。
圖1 抽象文法樹Java程式片段執行個體
根據Eclipse AST的定義,圖中每一個節點對應一個節點名,每一個子節點也在其依附的父節點中扮演着一個角色(身份),并且葉子節點基本為名稱、操作符和字面量。表1給出了圖1中的for循環節點(ForStatement)的四個子節點的節點名和依附于父節點的角色。
子節點 | 子節點名 | 依附于父節點的角色 |
int i = 1 | VariableDeclarationExpression | INITIALIZERS |
i <= 10 | InfixExpression | EXPRESSION |
i++ | PostExpression | UPDATERS |
{ count = count + 1; } | Block | BODY |
為了更直覺地閱讀和了解AST,可以使用ASTView等工具。ASTView(http://www.eclipse.org/jdt/ui/astview/)是一款Eclipse官方提供的抽象文法樹浏覽插件,可用來浏覽Eclipse編輯器中的代碼對應的抽象文法樹。在官方網站下載下傳插件後放入Eclipse安裝目錄下的dropins檔案夾中(Eclipse 3.4 M3以下版本放入plugins檔案夾中),打開Eclipse後在Window-Show View下找到ASTView點選(如圖2),即可打開ASTView視圖(如圖3)。
圖2 打開ASTView
圖3 ASTView視圖
下面是一個完整的Java類的源代碼:
package com.ast.usecase;
public class ClassDemo {
private String text = "Hello World!";
public void print(int value) {
System.out.println(value);
}
}
從ASTView的顯示結果來看,這貨生成的抽象文法樹居然有32個節點!
圖4 ASTView顯示結果
ASTView中所展示的除了抽象文法樹的節點外,還顯示相關的屬性,是以哪怕隻是一個小而簡單的類,一眼看遍整棵樹還是不太現實的。
圖5 ASTView常用功能按鈕
圖5是ASTView的一組常用功能按鈕,從左到右依次為:
- Show AST of active editor:展示編輯器光标目前所在位置的節點
- Refresh AST:當編輯器中代碼有所改動後,點選重新整理抽象文法樹
- Clear AST and release memory:關閉目前抽象文法樹的顯示
- Home:與Back和Go Into配合使用,傳回全局根節點,檢視子樹
- Back:與Home和Go Into配合使用,傳回父節點,并以父節點為根節點,檢視其子樹
- Go Into:與Home和Back配合使用,以目前所在節點為根節點,檢視其子樹
- Expand Selected Node:展開目前所選節點,以檢視其子節點
- Collapse Selected Node:折疊目前所選節點
- Link With Editor:關聯ASTView與編輯器,動态顯示光标所在的節點
輕按兩下ASTView中的任一節點,可以在編輯器中看到對應的代碼片段被高亮顯示。配合以上功能按鈕的使用能夠非常直覺、友善的浏覽代碼的抽象文法結構。
圖6 ASTView輕按兩下節點高亮顯示代碼
代碼雖小,五髒俱全。圖7是這個小而簡單的類所包含的32個節點以節點名和節點内容的形式制作成的樹狀圖【PS:韬韬童鞋畫這個圖可是費了大力氣的,
】,大家可以認真感受一下(對照源代碼和抽象文法樹)。
圖7 示例類ClassDemo所對應的完整抽象文法樹
了解了抽象文法樹和Java程式的文法結構後,接下來我們将學習如何使用Eclipse AST操作和生成Java源代碼,欲知詳情,請聽下回分解!
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiYWan5SZslWbz9CX0xWdhZWZk9CX09Wbl9lcvRXakVGa49CXy9GdpRWZoh3LcRXZu5ibkN3Yuc2bsJmLjlGdhR3cvw1LcpDc0RHaiojIsJye.gif)
【本文作者:劉偉,劉宏韬 http://blog.csdn.net/lovelion】