Java:我需要以编程方式解析,修改和回写Java源文件

时间:2015-10-12 09:40:35

标签: java parsing

我需要解析,修改和写回Java源文件。我调查了一些选项,但它接缝我错过了重点。

写回文件时解析AST的输出总是使用标准格式而不是原始格式搞砸了格式。

基本上我想要的东西可以做:content(write(parse(sourceFile)))。equals(content(sourceFile))。

我尝试了JavaParser但失败了。我可能会使用Eclipse JDT的解析器作为独立的解析器,但这感觉很重。我也想避免做自己的事情。例如,Java解析器已经有关于列和行的信息,但是将其写回接缝以忽略这些信息。

我想知道如何在输出与输入(意图,线,一切)相同的情况下实现解析和写回。基本上是一种保留原始格式的解决方案。

[更新]

我想要做的修改基本上是AST可能做的一切,比如添加,删除已实现的接口,删除/添加最终到局部变量,但也生成源方法和构造函数。

这个想法是添加/删除任何内容,但是如果结果行大于页边距,则其余部分需要保持不变,尤其是方法和表达式的格式化。

3 个答案:

答案 0 :(得分:0)

您可以尝试将antlr4与其java8 grammar file

一起使用

默认情况下,语法会跳过所有空格,但基于令牌位置,您可以重建靠近原始空格的源

答案 1 :(得分:0)

REx生成的解析器的输出是写入此接口的一系列事件:

public interface EventHandler
{
    public void reset(CharSequence input);
    public void startNonterminal(String name, int begin);
    public void endNonterminal(String name, int end);
    public void terminal(String name, int begin, int end);
    public void whitespace(int begin, int end);
}

其中整数偏移到输入中。事件流可用于构造解析树。由于事件流完全覆盖了所有输入,因此生成的数据结构可以毫无损失地表示它。

有一个示例驱动程序,在此接口之上实现XmlSerializer。流出一个XML解析树,它只是添加到输入的标记。因此,XML文档的字符串值与原始输入相同。

要查看它的实际效果,请使用Java 7 sample grammar并使用命令行生成解析器

-ll 2 -backtrack -tree -main -java

然后运行生成的Java.java的main方法,传入一些Java源文件名。

答案 2 :(得分:0)

我们的DMS Software Reengineering Toolkit及其Java Front End可以执行此操作。

DMS是program transformation system (PTS),旨在将源代码解析为内部表示(通常是AST),让您对这些树进行更改,并为修改后的树重新生成有效的输出文本。

好的PTS将在您未更改代码或生成格式良好的结果(包括原始来源中的注释)的地方保留您的格式/布局。它们还允许您以下列形式编写源到源的转换:

  if you see *this* pattern, replace it by *that* pattern

其中pattern以目标语言的表面语法编写(在本例中为Java)。编写这样的转换通常比编写程序代码以爬上树和检查单个节点要容易得多。

DMS拥有所有这些属性,包括OP对null变换的幂等性的请求。

[对另一个答案作出反应:是的,它有Java 8语法]