1

我目前正在分析Java源代码。我通过使用 Compiler Tree API 解析源代码来完成 AST 分析。但是我有一个问题,将新的 AST 节点(例如插入表达式或语句)添加到编译单元,以后可以由 Java 编译器编译。我没有找到任何方法或类可以做到这一点。

4

1 回答 1

1

我不认为 Java 编译器旨在让您从 AST 重新生成源代码。毕竟,它没有这个必要。

如果要修改程序,可以考虑使用源到源程序转换系统 (PTS)。这些是解析源代码(构建 AST)的工具,允许您使用以已解析源代码的语法编写的源到源转换规则,对 AST 进行更改,并可以从 AST 重新生成源文本。

PTS 规则本质上是说,“如果你看到这个,就用那个替换它”。我们的 PTS(DMS 软件再造工具包)的示例:

rule convert_square_to_multiply:(b: primitive_expression):product -> product
  =  "  \b ** 2 "  ->   " \b * \b " 
  if no_side_effects(b);

此规则找到一个表达式,提高到 2 次方,并应用经典的编译器“强度降低”来降低评估成本。注意 b 上的额外语义检查约束;您的 PTS 必须能够帮助您实施此类“分析”。

该规则通过以下方式起作用:

  • 将解析后的源程序的 AST 与规则左侧的模式所暗示的 AST 相匹配(“如果你看到这个......”)
  • 匹配时,模式变量(“b”)绑定到相应的子树
  • 检查“if”条件以验证它是否为真,
  • 如果是这样,匹配的子树将被删除并替换为规则右侧隐含形状的树(“用这个替换它”)

所有这一切的美妙之处在于无需编写糟糕的程序代码来爬上爬下树、检查节点类型、拼接节点进出等即可操纵 AST。源到源的重写更容易编写、检查和维护。

如果您不能使用 PTS,您可以考虑构建自己的 Prettyprinter;请参阅我的关于如何做到这一点的答案。我怀疑 Java 编译器捕获了足够的信息来重新生成“漂亮”的源代码。它可能足以重新生成可编译的源代码。举个例子,我很确定 Java 编译器 AST 不会保留注释。因此,它们将很难再生。一个标准的 PTS 捕获并复制所有这些东西。

于 2015-04-11T09:32:01.170 回答