java - ANTLR:通过stringtemplate将修改后的AST翻译成java源码

标签 java antlr pretty-print abstract-syntax-tree stringtemplate

我使用 ANTLR 中的语法 Java.g wiki 为 Java 源文件生成词法分析器和解析器。然后使用以下代码生成一个 abstract syntax tree (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。例如,替换“File file = new File(filepath, fileType);”到 “S3Object _file = new S3Object(_fileName);”通过修改 AST 节点。在此之后,我想将此 AST 转换为 java 源代码。我修改了 JavaTreeParser.g 并编写了一个 stringtemplate 并使用以下方法获取 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

如果我不修改AST,它会正确获取java源代码,但是我修改AST后,它没有获取正确的java源代码(AST被正确修改)。例如,如果我输入以下源代码,并翻译成AST,然后修改“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
  }

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

最佳答案

不幸的是,我不推荐通过重写抽象语法树来进行源到源的翻译;尝试使用解析树。如果我记得 ANTLR 3 也可以轻松生成这些。 三

关于java - ANTLR:通过stringtemplate将修改后的AST翻译成java源码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20344509/

相关文章:

python - 将 print+format 推广为可变数量的输入

java - 如何在另一个 Controller 中覆盖@RequestMapping?

java - 如何将自定义 Antlr 输出路径添加到 Gradle 中的主源集?

parsing - ANTLR 与预煮

haskell - Haskell 中具有运算符优先级和关联性的 pretty-print 语法树

javascript - 如何修复 Google 美化 HTML 转义序列的处理

java - 无法在网格布局中的卡片 View 项目 ClickListener 上显示 Toast 消息或打开新 Activity ...!

java - 在Java的synchronizedList中使用break和return会执行不需要的行为

java - 双变量实现和不同的输出

Erlang 和 Antlr