[英]Generating an Abstract Syntax Tree for java source code using ANTLR
如何使用ANTLR從java src代碼生成AST?
任何幫助?
好的,這是步驟:
Java.g
和JavaTreeParser.g
文件。 運行以下命令:
java -jar antlrTool Java.g java -jar antlrTool JavaTreeParser.g
將生成5個文件:
使用此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);
}
}
}
使用antlr4生成java src AST的setps是:
現在使用以下命令生成Java8Lexer和Java8Parser:
antlr4 -visitor Java8.g4
這將生成幾個文件,如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那么你可以參考這個 QnA帖子或直接引用我使用gradle來構建項目的這個存儲庫 。
希望這可以幫助。 :)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.