2017-10-03 31 views
1

私はCソースファイルを取得し、すべての関数呼び出しの始めにいくつかのコードを挿入するプロジェクトに取り組んでいます。 Mainはファイルをロードして文字列に変換します。ファイルをANTLRで解析した後にファイルを保存するにはどうすればいいですか?

Main.java

  String inputFilename = args[0]; 
      byte[] bytes = Files.readAllBytes(Paths.get(inputFilename)); 
      String code = new String(bytes, StandardCharsets.UTF_8); 

      Translator translator = new Translator(code); 
      translator.translate(); 

翻訳者クラスがANTLRInputStreamCLexer、とCommonTokenStreamを作成します。次に、CodeListenerクラスを使用してツリーを歩きます。

Translator.java

public Translator(String code){ 
    ANTLRInputStream inputStream = new ANTLRInputStream(code); 
    CLexer lexer = new CLexer(inputStream); 
    tokens = new CommonTokenStream(lexer); 
    CParser parser = new CParser(tokens); 
    parseTree = parser.compilationUnit(); 
} 

void translate(){ 
    walker = new ParseTreeWalker(); 
    CodeListener listener = new CodeListener(tokens); 
    walker.walk(listener, parseTree); 
    parsedCode = listener.rewriter.getText(); 
    saveFile(); 
} 

void saveFile(){ 
    try (PrintStream out = new PrintStream(new FileOutputStream("filename.txt"))){ 
     out.print(parsedCode); 
    } catch (Exception e){ 
     e.printStackTrace(); 
    } 
} 

}

CodeListenerクラスは、関数本体の先頭にコメント、//hey look a functionを挿入します。

CodeListener.java

public TokenStreamRewriter rewriter; 
String parsedCode = ""; 
@Override 
public void enterFunctionDefinition(CParser.FunctionDefinitionContext ctx) { 

    String returnType = ctx.declarationSpecifiers().getText(); 
    String functionBody = ctx.compoundStatement().getText(); 
    rewriter.insertBefore(ctx.compoundStatement().getStart(), "//hey look a function "); 
} 

私は修正されたストリームを見つけましたが、私は新しく変更されたコードを取得することができます方法はありますか?下の例に示すように、ファイルをparsedcode.cなどに保存するにはどうすればよいですか?

code.c

int main(){ 
    foo(); 
    bar(); 
} 

void foo(){ 
    //does something 
} 

void bar(){ 
    //does something else 
} 

parsedcode.c

int main(){ 
    //hey look a function 
    foo(); 
    bar(); 
} 

void foo(){ 
    //hey look a function 
    //does something 
} 

void bar(){ 
    //hey look a function 
    //does something else 
} 

答えて

1

は、あなただけのTokenStreamRewritertoString()または何を呼び出すと、文字列を保存することができませんか?

+0

はい、ちょうどそれを働かせて、私は空白を含める必要があります。私は、WS:[\ t \ n \ r] - >チャンネル(WHITESPACE);の前に 'WS:[\ t \ n \ r] - >スキップ; '@lexer :: members { }パブリックstatic final int WHITESPACE = 1;これは、 } 'この本の中で助けてくれてありがとう! – ryanmattscott

関連する問題