ANTLR:使用StringTemplate将修改后的AST翻译成Java源代码

3
我使用来自ANTLR维基的Java.g语法生成Java源文件的词法分析器和语法分析器。然后使用以下代码生成抽象语法树(AST)
    ANTLRInputStream input = new ANTLRInputStream(new FileInputStream(fileName));
    JavaLexer lexer = new JavaLexer(input);     // create lexer
    // create a buffer of tokens pulled from the lexer
    CommonTokenStream tokens = new CommonTokenStream(lexer);
    JavaParser parser = new JavaParser(tokens); // create parser
    JavaParser.javaSource_return r = parser.javaSource();   // parse rule 'javaSource'
    /*RuleReturnScope result = parser.compilationUnit();
    CommonTree t = (CommonTree) result.getTree();*/
    // WALK TREE
    // get the tree from the return structure for rule prog
    CommonTree t = (CommonTree)r.getTree();

然后修改AST。例如,通过修改AST节点将“File file = new File(filepath,fileType);”替换为“S3Object _file = new S3Object(_fileName);”。完成后,我想将该AST转换为Java源代码。我修改了JavaTreeParser.g、编写了一个字符串模板,并使用以下方法获取Java源代码:
    FileReader groupFileR = new FileReader("src/com/googlecode/zcg/templates/JavaTemplate.stg");
    StringTemplateGroup templates = new StringTemplateGroup(groupFileR);
    groupFileR.close();
    // create a stream of tree nodes from AST built by parser
    CommonTreeNodeStream nodes = new CommonTreeNodeStream(t);
    // tell it where it can find the token objects
    nodes.setTokenStream(tokens);
    JavaTreeParser walker = new JavaTreeParser(nodes); // create the tree Walker
    walker.setTemplateLib(templates); // where to find templates
    // invoke rule prog, passing in information from parser
    JavaTreeParser.javaSource_return r2 = walker.javaSource();

    // EMIT BYTE CODES
    // get template from return values struct
    StringTemplate output = (StringTemplate)r2.getTemplate(); 
    System.out.println(output.toString()); // render full template

如果我不修改语法树,它可以正确地获取Java源代码,但是在我修改语法树后,它无法获得正确的Java源代码(语法树已经正确修改)。例如,如果我输入以下源代码,并将其转换为语法树,然后将“File file = new File(filepath, fileType);”修改为“S3Object _file = new S3Object(_fileName);”:

public void methodname(String address){
    String filepath = "file";
    int fileType = 3;       
    File file = new File(filepath, fileType);
}

结果将如下所示:
public void methodname( String address)
  { 
     String filepath="file";
     int fileType=3;
     methodname (Stringaddress){Stringfilepath;//it's not  what I wanted
  }

我做错了吗?有没有更合适的方法来解决这个问题?

1个回答

2

很遗憾,我无法推荐通过重写抽象语法树来进行源代码的翻译;建议使用解析树。如果我没记错,ANTLR 3也可以轻松生成这些。


谢谢。我需要从树中获取变量的类型并修改树,但是解析树比抽象语法树要复杂得多。解析树能完成这样的任务吗? - Tony Wang
解析树更大,但使源到源的转换更容易。ANTLR 4.2将会有很大帮助。请查看主分支以获取树模式相关内容。 - Terence Parr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接