0

我有兴趣比较代码以找到匹配项,即查看两个不同的代码是否等效。例如,对于返回两个数字之和的方法(在 Java 中),这里有 4 个匹配项。

int sum(int a, int b){
  return a + b;
}

int sum(int a, int b){
  return b + a;
}

int sum(int a, int b){
  int sum = a + b;
  return sum; 
}

int sum(int a, int b){
  int total = a + b;
  return total; 
}

虽然很容易对两段源代码进行文本比较,但很难编写能够识别上述匹配项的代码。这似乎是解析器或编译器的工作,但它不需要“完美”,因为它只是在寻找匹配项。

这是针对 Rails 网站的,因此理想情况下它应该能够在 Ruby 中工作,但我也可以运行单独的服务。Treetop是一种描述语法的语言,但描述语法也很困难。是否有现有工具可以比较多种语言(如 Java、C++、Ruby 和 Python)的源代码?

它只需要一次找到一种语言的源代码之间的匹配项,但如果它也能找到不同语言的源代码之间的匹配项,那就太酷了。

更新:匹配不是任何产生相同结果的代码,而是使用相同过程和步骤来获得相同结果的代码。该工具不需要找到所有可能的匹配项,但它应该能够识别除了小的差异之外的相同代码,例如变量名称或顺序(如上例所示)。

4

3 回答 3

3

这个问题被称为函数问题:找出两个程序是否计算相同的函数。已知它是不可判定的,即这种工具不可能存在。

基本上,如果您有这样的工具,那么您可能会问:是否有某个程序P等效于该程序:

while (true);

你就会解决停机问题。(这实际上并不是证明的方式,它比这要复杂得多,但这是基本思想。)

于 2013-11-14T16:24:42.153 回答
1

对于 ruby​​,请查看https://github.com/seattlerb/flay 对于 C# Resharper 可以被告知寻找忽略名称的特定代码结构。不完全是您正在寻找的,但功能强大。

我不知道可以让您在语言之间进行比较....除非您使用 Reflector,您可以将 .net 字节码反编译回 C#,然后使用 resharper,从而在 .net 语言之间进行转换。

于 2013-11-15T05:22:21.260 回答
1

查看PMD CPD,它支持多种语言,并且在比较过程中也有一些关于忽略什么的好主意等。

还要看缩小。您可能会对此进行改进,因为您不需要像缩小器那样仍然将结果作为代码工作。但是你可能不会找到很多编译语言的缩小器。我在这里看到的还有一个潜在的陷阱 - 例如,两个函数的缩小版本在缩小时可能会变得不太相似,具体取决于缩小器如何重命名参数(它们通常只是按顺序命名它们,例如ab, c,...)。

Nigel 提到将 .NET 语言编译为字节码,然后反编译 - JVM 字节码也可以这样做,甚至二进制文件(或 LLVM IR 之类的东西)也可以,但其中大部分对于你正在尝试的东西来说太低级了要做到这一点,每种方法仅涵盖几种语言,并且对于某些方法来说也可能非常困难或不可能。

如果您想对一种通用语言进行非常简单的近似,您可以尝试选择一些常见的东西,例如函数头、循环、大括号/缩进,并尝试使用非常简单的解析器使语言更加相似(仅使用 text-replace和正则表达式,例如)。例如,您可以用 替换 Java public int func(int a, char b)def func(a,b)而对于 Ruby、Scala 和 Python,在这种情况下您几乎不需要做任何事情。这是一个糟糕的想法,但其中一些转换很容易编写,所以如果所有其他方法都失败了,请尝试看看它是否能让你有所收获。如果你这样做了,记得编写单元测试——复杂语言的简单解析器很容易出错。

编辑:还要看的一件事可能是编程作业抄袭检测器,例如http://theory.stanford.edu/~aiken/moss/

于 2013-11-16T16:50:20.980 回答