有没有可以比较或解析多种语言的工具?

时间:2013-11-14 14:05:41

标签: ruby-on-rails ruby parsing static-analysis abstract-syntax-tree

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

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)?

它只需要一次找到一种语言的源代码之间的匹配,但如果能找到不同语言的源代码之间的匹配则会很酷。

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

3 个答案:

答案 0 :(得分:3)

这个问题被称为功能问题:确定两个程序是否计算相同的功能。众所周知,它是不可判定的,即这种工具不可能存在。

基本上,如果您有这样的工具,那么您可以问:是否有一个与此程序等效的程序P

while (true);

你会解决停机问题。 (那不是实际证明如何进行,它比那复杂得多,但这是基本的想法。)

答案 1 :(得分:1)

对于红宝石,请查看https://github.com/seattlerb/flay 对于C#,Resharper可以被告知寻找忽略名称的特定代码结构。不是你想要的,但功能强大。

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

答案 2 :(得分:1)

查看支持多种语言的PMD CPD,并对比较期间忽略的内容提供一些好的建议。

另见minification。你可能可以改进,因为你不需要结果仍然像代码一样工作,就像minificators一样。但是你可能找不到很多编译语言的缩写器。我在这里也看到了一个潜在的缺陷 - 例如,两个仅具有参数shuffled的函数的缩小版本在缩小时可能变得不那么相似,这取决于缩小器如何重命名参数(它们通常只是按顺序命名,例如{ {1}},ab,...)。

Nigel提到将.NET语言编译为字节码,然后反编译 - 对于JVM字节码也是可能的,甚至可能用于二进制文件(或LLVM IR之类的东西),但是大部分内容对于你来说太低了我试图这样做,每种方法只涵盖几种语言,而且某些方法也很难或不可能。

如果你想对公共语言进行非常粗略的近似,你可以尝试选择一些常见的东西,比如函数头,循环,大括号/缩进,并尝试使用非常简单的解析器使语言更相似(仅使用例如,text-replace和regexes)。例如你可以用c替换Java的public int func(int a, char b),对于Ruby,Scala和Python,在这种情况下你几乎不需要做什么。这是一个可怕的想法,但其中一些转换很容易编写,所以如果所有其他方法都失败了,请试着看看它是否能让你随处可见。如果你这样做,记得编写单元测试 - 复杂语言的简单解析器很容易破解。

编辑:还要注意的一件事可能是编写家庭作业抄袭探测器,例如: http://theory.stanford.edu/~aiken/moss/