语义差异工具

我试图find语义差异/合并实用程序的一些很好的例子。 比较源代码文件的传统范例是通过比较行和字符来工作的。但是在比较文件时是否有实际考虑代码结构的任何实用程序(对于任何语言)?

例如,现有的diff程序将报告“在第125行的字符2处发现的差异。文件x包含void,其中文件y包含bool”。 一个专门的工具应该能够报告“方法doSomething()的返回types从void更改为bool”。

我认为这种types的语义信息实际上是用户在比较代码时所要查找的内容,应该是下一代编程工具的目标。 有没有这样的可用工具的例子?

我们开发了一个能够精确处理这种情况的工具。 检查http://www.semanticmerge.com

它基于代码结构合并(和差异),而不是使用基于文本的algorithm,它基本上允许你处理类似下面的情况,涉及强重构。 它也能够渲染差异和合并冲突,如下所示:

在这里输入图像说明

而不是混淆正在移动的文本块,因为它首先parsing,它能够显示每个方法的基础上的冲突(实际上每个元素)。 像以前的情况下,甚至没有手动冲突来解决。

在这里输入图像说明

这是一个语言意识的合并工具,最后终于能够回答这个问题了:-)

Eclipse已经有了这个function很长一段时间了。 这就是所谓的“结构比较”,这是非常好的。 下面是Java的示例屏幕截图,其次是XML文件:

(请注意上方窗格中方法的减号和加号图标。)

Eclipse的Java结构比较器 Eclipse的XML结构比较器http://help.eclipse.org/ganymede/topic/org.eclipse.pde.doc.user/whatsNewhttp://img.dovov.comxml-compare.png

要做好“语义比较”,你需要比较语言的语法树,并考虑符号的含义。 一个非常好的语义差异可以理解语言语义,并且当一个代码块在function上与另一个代码块相同时,就可以实现这一点。 要做到这一点需要一个定理certificate,虽然它是非常可爱的,但对于一个真正的工具来说目前还不是很实用。

一个可行的近似就是比较语法树,并根据插入,删除,移动或更改的结构报告更改。 为了更接近“语义比较”,可以报告标识符在一段代码中是否一致地变化。

请参阅我们的http://www.semanticdesigns.com/Products/SmartDifferencer/index.html,了解基于语法树的比较引擎,该引擎可以与多种语言一起使用,可以实现上述近似。;

编辑2010年1月:可用于C ++,C#,Java,PHP和COBOL的版本。 该网站显示了大多数这些具体的例子。

编辑2010年5月:添加了Python和JavaScript。

编辑2010年10月:EGL补充。

编辑2010年11月:VB6,VBScript,VB.net补充

你正在摸索的是一个“树差异”。 事实certificate,这比一个简单的面向行的文本差异要好得多,这实际上只是两个平面序列的比较。

“ 细粒度的XML结构比较方法 ”的结论部分是:

我们的理论研究以及我们的实验评估表明,所提出的方法在相同的时间复杂度(O(N ^ 2))下产生改进的结构相似性结果

(重点是我的)

事实上,如果你正在寻找更多的树形差异化的例子,我build议把重点放在XML上,因为这正在推动这个领域的实际发展。

无耻的插件为我自己的项目:

HTML Tree Diff用python编写了xml和html文档的结构感知比较。

http://pypi.python.org/pypi/html-tree-diff/0.1.0

对此的解决scheme将在每个语言的基础上。 也就是说,除非它devise了一个插件体系结构,这个插件体系结构将许多代码parsing到一个树中,并将语义比较为一个语言特定的插件,那么支持多种语言将是非常困难的。 你有兴趣使用这种工具的语言是什么? 我个人很喜欢C#。

对于C#,有一个程序集diffjoin到reflection器,但它只是在IL而不是C#上进行diff。

你可以在这里下载diff加载项[zip],或者到codeplex网站的项目上。

一家名为Zynamics的公司提供了一个二进制级别的语义比较工具。 它使用称为REIL的元组合语言对二进制的2个版本进行图论分析,并产生一个颜色编码的图表来说明它们之间的差异。 我不确定价格,但我怀疑它是免费的。

http://prettydiff.com/

Pretty Diff将每个input缩小为删除注释和不必要的空白,然后在diffalgorithm之前美化代码。 反正我想不出更多的代码语义。 而且,其书面的JavaScript,所以它直接在浏览器中运行。