要想自己设计并实现一个代码自动分析、优化和重构工具,得先理解代码;要想理解代码,得先用一个好的数据结构来存储和表示所读取的代码。基于程序代码本身的层次结构,用树状结构来表示是再好不过的了,。
抽象语法树(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源代码,欲知详情,请听下回分解!
【本文作者:刘伟,刘宏韬 http://blog.csdn.net/lovelion】