java解析java源码_使用openjdk的语法解析器(Parser)解析java源代码

jsr269提供annotation processor,允许我们在编译器编译过程中挂钩子。http://projectlombok.org/ 的许多功能正是基于此实现。

但有时候可能需要解析语法正确,但没有语义的Java文件(比如对工程中的单个java源文件的方法等元素建索引),这个时候jsr269就不能满足需求了。此时,我们只要语法树(ast)就可以了,也就是说不需要编译通过,只需要语法解析,可选的parser我找到了3个:

-- antlr parser

-- eclipse jdt parser

-- javac parser

下面一个例子使用javac parser来获得ast,并采用visitor模式遍历整颗语法树,提取文件中的所有方法。

注意:

需要在classpath中引入jdk的tools.jar

很多类不属于标准api,目前只在openjdk6,7上做过测试

package org.jilen;

import java.io.FileInputStream;

import java.io.IOException;

import java.nio.ByteBuffer;

import java.nio.channels.FileChannel;

import java.nio.channels.FileChannel.MapMode;

import java.nio.charset.Charset;

import java.util.ArrayList;

import java.util.List;

import com.sun.source.tree.MethodTree;

import com.sun.source.util.TreeScanner;

import com.sun.tools.javac.file.JavacFileManager;

import com.sun.tools.javac.parser.Parser;

import com.sun.tools.javac.parser.ParserFactory;

import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;

import com.sun.tools.javac.util.Context;

public class JDKParser {

private ParserFactory factory;

public JDKParser() {

factory = getParserFactory();

}

public List parseMethodDefs(String file) throws IOException {

JCCompilationUnit unit = parse(file);

MethodScanner scanner = new MethodScanner();

return scanner.visitCompilationUnit(unit, new ArrayList());

}

JCCompilationUnit parse(String file) throws IOException {

Parser parser = factory.newParser(readFile(file), true, false, true);

return parser.parseCompilationUnit();

}

private ParserFactory getParserFactory() {

Context context = new Context();

JavacFileManager.preRegister(context);

ParserFactory factory = ParserFactory.instance(context);

return factory;

}

CharSequence readFile(String file) throws IOException {

FileInputStream fin = new FileInputStream(file);

FileChannel ch = fin.getChannel();

ByteBuffer buffer = ch.map(MapMode.READ_ONLY, 0, ch.size());

return Charset.defaultCharset().decode(buffer);

}

//扫描方法时,把方法名加入到一个list中

static class MethodScanner extends

TreeScanner, List> {

@Override

public List visitMethod(MethodTree node, List p) {

p.add(node.getName().toString());

return p;

}

}

public static void main(String[] args) throws IOException {

JDKParser parser = new JDKParser();

for (String method : parser.parseMethodDefs("User.java")) {

System.out.println(method);

}

}

}

1.parser.parseCompilationUnit();获得语法树

2.MethodScanner扫描整颗语法树,整个扫面其实是fold/reduce过程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值