如何在使用ANTLR(使用java)解析文件后保存文件?
我正在从事一个项目,在这个项目中,我将获取一个C源文件,并在每个函数调用的开始处注入一些代码如何在使用ANTLR(使用java)解析文件后保存文件?,java,antlr4,translate,filewriter,code-translation,Java,Antlr4,Translate,Filewriter,Code Translation,我正在从事一个项目,在这个项目中,我将获取一个C源文件,并在每个函数调用的开始处注入一些代码Main加载文件并将其转换为字符串 Main.java String inputFilename = args[0]; byte[] bytes = Files.readAllBytes(Paths.get(inputFilename)); String code = new String(bytes, StandardCharset
Main
加载文件并将其转换为字符串
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();
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();
}
}
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 ");
}
translator类创建AntlInputStream
、CLexer
、CParser
和CommonTokenStream
。然后它使用CodeListener
类遍历树
Translator.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();
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();
}
}
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 ");
}
}
CodeListener
类在函数体的开头插入注释,//hey look a function
CodeListener.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();
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();
}
}
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
,如下面的示例所示
代码.c
int main(){
foo();
bar();
}
void foo(){
//does something
}
void bar(){
//does something else
}
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
}
parsedcode.c
int main(){
foo();
bar();
}
void foo(){
//does something
}
void bar(){
//does something else
}
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
}
你不能调用
toString()
或TokenStreamRewriter
上的任何东西并保存字符串吗?是的,刚刚开始工作,但我需要包含空格。我将语法更改为在WS:[\t\n\r]>channel(空白)上发送代码>在它被WS:[\t\n\r]->跳过之前然后包括@lexer::members{public static final int WHITESPACE=1;}
在书中发现,感谢您的帮助!