UDN-企业互联网技术人气社区

板块导航

浏览  : 646
回复  : 1

[讨论交流] Java代码分析器(一): JDT入门

[复制链接]
开花包的头像 楼主
发表于 2016-8-4 21:58:23 | 显示全部楼层 |阅读模式
  这是一个关于抽象语法树(Abstract Syntax Tree, AST)的故事。

  抽象语法树是对程序代码的结构化表示,是对代码进行词法分析、语法分析后得到的产物。编译器要用到它,很多生产力工具也要用它,例如:

  IDE可以自动重构、自动生成一些代码、自动对不规范代码发出警告。这是很强很实惠的功能。

  一个大型软件项目常常有几百人合作,几百万行代码。很多代码规范难以百分百落实,很多编程错误潜藏在项目中。这时候我们会考虑Sonar, FindBug, Checkstyle之类的代码分析工具来帮助我们扫描出巨量代码中存在的问题。

  国内有位老兄就做了个自动生成测试代码的工具。(但不要生成功能代码,我们要构建良好的抽象和简洁的代码)

  我司的系统要进行架构迁移,其中有百万行代码需要修改,用人力来做是很可怕的。我做了个工具来自动完成这件事。

  它们利用AST来对大量程序代码做自动化处理,给了我们莫大的帮助。甚至自动写代码也不是不可能。那么我们自己能玩一玩AST这种高大上的东西吗?

  能。Eclipse这个开源的Java IDE就提供了一个库来帮助我们达到目的,它的名字是JDT(Java Development Tools)。我们使用它的核心模块JDT Core。

  这个项目历史悠久,功能强力,早期开发者有《设计模式》GoF的作者。

  它提供了一套关于AST的API,能解析Java代码,生成、分析和操作AST结构。有了它,我们就不用自己实现高难度的词法分析和语法分析了。

  动手搞起

  (嫌麻烦可以看这个小框架 https://github.com/sorra/exia)

  首先准备好库文件——打开你的Eclipse安装目录,在搜索框中搜索以下jar文件(*是通配符):

  org.eclipse.jdt.core*

  org.eclipse.core.contenttype

  org.eclipse.core.jobs_

  org.eclipse.core.resources*

  org.eclipse.core.runtime

  org.eclipse.equinox.common_

  org.eclipse.equinox.preferences*

  org.eclipse.equinox.registry

  org.eclipse.osgi_

  org.eclipse.text*

  如果有多个版本,取最新版本。统统copy出来,添加到你的项目中。

  源代码包是org.eclipse.jdt.core.source* 用Eclipse的Attach source功能把它连到第一个jar上,可以阅读源代码。

  先来溜一段起步代码,把一段Java代码解析成AST。

  1. import java.util.Map;  
  2. import org.eclipse.jdt.core.dom.*;  
  3. import org.eclipse.jdt.JavaCore;  
  4. ......  
  5. public static void main(String[] args) {  
  6.     ASTParser parser = ASTParser.newParser(AST.JLS4); //设置Java语言规范版本  
  7.     parser.setKind(ASTParser.K_COMPILATION_UNIT);  

  8.     Map<String, String> compilerOptions = JavaCore.getOptions();  
  9.     compilerOptions.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_7); //设置Java语言版本  
  10.     compilerOptions.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_7);  
  11.     compilerOptions.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_7);  
  12.     parser.setCompilerOptions(compilerOptions); //设置编译选项  

  13.     char[] src = "class A { void method1(int b){;} }".toCharArray();
  14.     parser.setSource(src);

  15.     CompilationUnit cu = (CompilationUnit) parser.createAST(null); //这个参数是IProgessMonitor,用于GUI的进度显示,我们不需要,填个null. 返回值是AST的根结点

  16.     System.out.println(cu); //把AST直接输出看看啥样
  17. }
复制代码


  AST作为抽象语法树,它就是一棵树,有点像XML的DOM树。 例子中的树大概长这样:

  1.  CompilationUnit
  2.        |
  3.      class
  4.     |     |
  5.     A   method1
  6.        |   |   |
  7.      void []   {}
  8.            |   |
  9.           arg  ;
  10.          |  |
  11.         int b
复制代码


  延伸阅读:http://help.eclipse.org/ 点击JDT Plug-in User Guide -> Programmer's Guide -> JDT Core。

原文作者:sorra    来源:开发者头条

相关帖子

发表于 2016-8-5 13:40:01 | 显示全部楼层
抽象语法树是对程序代码的结构化表示,是对代码进行词法分析、语法分析后得到的产物。编译器要用到它,很多生产力工具也要用它
使用道具 举报

回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关于我们
联系我们
  • 电话:010-86393388
  • 邮件:udn@yonyou.com
  • 地址:北京市海淀区北清路68号
移动客户端下载
关注我们
  • 微信公众号:yonyouudn
  • 扫描右侧二维码关注我们
  • 专注企业互联网的技术社区
版权所有:用友网络科技股份有限公司82041 京ICP备05007539号-11 京公网网备安1101080209224 Powered by Discuz!
快速回复 返回列表 返回顶部