使用ANTLR为java源代码生成抽象语法树

如何使用ANTLR从java src代码生成AST?
任何帮助?

使用antlr4生成java src AST的setps是:

  1. 安装antlr4你可以使用这个链接来做到这一点。
  2. 安装后从这里下载JAVA语法 。
  3. 现在使用以下命令生成Java8Lexer和Java8Parser:

    antlr4 -visitor Java8.g4

  4. 这将生成几个文件,如Java8BaseListener.java Java8BaseVisitor.java Java8Lexer.java Java8Lexer.tokens Java8Listener.java Java8Parser.java Java8.tokens Java8Visitor.java

使用此代码生成AST:

 import java.io.File; import java.io.IOException; import java.nio.charset.Charset; import java.nio.file.Files; import org.antlr.v4.runtime.ANTLRInputStream; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.ParserRuleContext; import org.antlr.v4.runtime.RuleContext; import org.antlr.v4.runtime.tree.ParseTree; public class ASTGenerator { public static String readFile() throws IOException { File file = new File("path/to/the/test/file.java"); byte[] encoded = Files.readAllBytes(file.toPath()); return new String(encoded, Charset.forName("UTF-8")); } public static void main(String args[]) throws IOException { String inputString = readFile(); ANTLRInputStream input = new ANTLRInputStream(inputString); Java8Lexer lexer = new Java8Lexer(input); CommonTokenStream tokens = new CommonTokenStream(lexer); Java8Parser parser = new Java8Parser(tokens); ParserRuleContext ctx = parser.classDeclaration(); printAST(ctx, false, 0); } private static void printAST(RuleContext ctx, boolean verbose, int indentation) { boolean toBeIgnored = !verbose && ctx.getChildCount() == 1 && ctx.getChild(0) instanceof ParserRuleContext; if (!toBeIgnored) { String ruleName = Java8Parser.ruleNames[ctx.getRuleIndex()]; for (int i = 0; i < indentation; i++) { System.out.print(" "); } System.out.println(ruleName + " -> " + ctx.getText()); } for (int i = 0; i < ctx.getChildCount(); i++) { ParseTree element = ctx.getChild(i); if (element instanceof RuleContext) { printAST((RuleContext) element, verbose, indentation + (toBeIgnored ? 0 : 1)); } } } } 

完成编码后,您可以使用gradle构建项目,也可以在项目目录中下载antlr-4.7.1-complete.jar并开始编译。

如果你想要一个DOT文件中的输出,以便你可以看到AST那么你可以参考这个 QnApost或直接引用我使用gradle来构建项目的这个存储库 。

希望这可以帮助。 🙂

好的,这是步骤:

  1. 转到ANTLR站点并下载最新版本
  2. 从此处下载Java.gJavaTreeParser.g文件。
  3. 运行以下命令:

     java -jar antlrTool Java.g java -jar antlrTool JavaTreeParser.g 
  4. 将生成5个文件:

    1. Java.tokens
    2. JavaLexer.java
    3. JavaParser.java
    4. JavaTreeParser.g
    5. JavaTreeParser.tokens

使用此java代码生成抽象语法树并打印它:

  String input = "public class HelloWord {"+ "public void print(String r){" + "for(int i = 0;true;i+=2)" + "System.out.println(r);" + "}" + "}"; CharStream cs = new ANTLRStringStream(input); JavaLexer jl = new JavaLexer(cs); CommonTokenStream tokens = new CommonTokenStream(); tokens.setTokenSource(jl); JavaParser jp = new JavaParser(tokens); RuleReturnScope result = jp.compilationUnit(); CommonTree t = (CommonTree) result.getTree(); CommonTreeNodeStream nodes = new CommonTreeNodeStream(t); nodes.setTokenStream(tokens); JavaTreeParser walker = new JavaTreeParser(nodes); System.out.println("\nWalk tree:\n"); printTree(t,0); System.out.println(tokens.toString()); } public static void printTree(CommonTree t, int indent) { if ( t != null ) { StringBuffer sb = new StringBuffer(indent); for ( int i = 0; i < indent; i++ ) sb = sb.append(" "); for ( int i = 0; i < t.getChildCount(); i++ ) { System.out.println(sb.toString() + t.getChild(i).toString()); printTree((CommonTree)t.getChild(i), indent+1); } } }