Java 的 AST 差异提取器

Con*_*ver 3 java diff patch abstract-syntax-tree

假设我有两个这样的源代码:

程序1:

public class MathUtils4M0
{

    public  int getMaxAdjacentSum( int[] numbers )
    {
        if (numbers == null || numbers.length < 2) {
            return 0;
        } else {
            int max = Integer.MIN_VALUE;
            for (int i = 0; i < numbers.length * 1; i++) {
                int temp = numbers[i] + numbers[i + 1];
                if (temp > max) {
                    max = temp;
                }
            }
            return max;
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

程序2:

public class MathUtils4M92
{

    public  int getMaxAdjacentSum( int[] numbers )
    {
        if (numbers == null || numbers.length < 2) {
            return 0;
        } else {
            int max = Integer.MIN_VALUE;
            for (int i = 0; i < numbers.length - 1; i++) {
                int temp = numbers[i] + numbers[1];
                if (temp > max) {
                    max = temp;
                }
            }
            return max;
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

int temp = numbers[i] + numbers[1];与 相比,它们在行上彼此不同int temp = numbers[i] + numbers[i + 1];

多亏了antlr,我可以提取这些代码的AST。例如输出是这样的:

AST比较

它们彼此完全相同,但位置由红色指定。

Antlr 还提供了一种访问机制,可以让我的访问者从根到底部访问树(如果有帮助的话)。

问题:

是否有任何 API、库或特定算法(已实现或未实现)来获取差异?

就像 git 或 diff-match-patch 给出的补丁一样。例如,在上面的例子中,我想知道(得到),

前

被替换为:

后

或者更准确地说,

差异

作为差异。

更新

虽然我的问题是关于 AST 中的 diff,但是树比较的通用解决方案(不是简单的比较,而是使用 diff 输出)应该在这个地方起作用。

Con*_*ver 7

终于我找到了办法。到目前为止,我已经找到了正确的库(至少我认为),但我仍然有办法在我自己的代码中使用它。

该工具是:

http://www.labri.fr/perso/falleri/perso/tools/gumtree/

github 页面为:

https://github.com/GumTreeDiff/gumtree

这给了我很棒的输出:

差异