2017-10-03 21 views
1

나는 C 소스 파일을 가져 와서 모든 함수 호출의 시작 부분에 몇 가지 코드를 삽입하는 프로젝트에서 일하고있다. Main은 파일을로드하고 문자열로 변환합니다.파일을 ANTLR로 구문 분석 한 후 파일을 저장하는 방법 (java 사용)?

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(); 

번역기 클래스는 ANTLRInputStream, CLexer, CParserCommonTokenStream 만듭니다. 그런 다음 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

당신은 toString()를 호출 할 수 없습니다 또는 무엇이든 TokenStreamRewriter에와 문자열을 저장?

+0

예, 작동하도록했습니다. 공백을 포함해야합니다. 문법을 변경하여 'WS : [\ t \ n \ r] -> 건너 뛰기'전에 채널 (WS : [\ t \ n \ r] -> 채널 (WHITESPACE) @lexer :: members { 공공 정적 final int WHITESPACE = 1; }'책 도움 덕분에 발견! – ryanmattscott