我试图找到一些语义差异/合并实用程序的好例子。比较源代码文件的传统范例是通过比较行和字符来实现的..但是,是否有任何实用程序(对于任何语言)在比较文件时实际考虑代码的结构?
例如,现有的差异程序将报告“在第125行的字符2处发现差异。文件x包含void,文件y包含bool”。一个专门的工具应该能够报告“方法doSomething()的返回类型从void变为bool”。
我认为这种类型的语义信息实际上是用户在比较代码时要寻找的信息,应该成为下一代编程工具的目标。可用工具中是否有此示例?
我试图找到一些语义差异/合并实用程序的好例子。比较源代码文件的传统范例是通过比较行和字符来实现的..但是,是否有任何实用程序(对于任何语言)在比较文件时实际考虑代码的结构?
例如,现有的差异程序将报告“在第125行的字符2处发现差异。文件x包含void,文件y包含bool”。一个专门的工具应该能够报告“方法doSomething()的返回类型从void变为bool”。
我认为这种类型的语义信息实际上是用户在比较代码时要寻找的信息,应该成为下一代编程工具的目标。可用工具中是否有此示例?
Answers:
我们开发了一种工具,可以精确处理这种情况。检查http://www.semanticmerge.com
它基于代码结构而不是基于文本的算法合并(和差异),这基本上使您可以处理以下涉及强重构的情况。它也能够呈现差异和合并冲突,如下所示:
由于它首先进行解析,因此不会与要移动的文本块产生混淆,而是能够基于每个方法(实际上是每个元素)显示冲突。像以前那样的情况甚至没有人为解决的冲突。
这是一种可识别语言的合并工具,很高兴终于能够回答这个SO问题:-)
为了更好地进行“语义比较”,您需要比较语言的语法树,并考虑符号的含义。一个真正好的语义差异将理解语言的语义,并实现一个代码块在功能上等同于另一个代码块。要走得太远,需要一个定理证明者,虽然它非常可爱,但是目前对于实际工具并不实用。
一个可行的近似方法是简单地比较语法树,并根据插入,删除,移动或更改的结构报告更改。更接近“语义比较”,可以在代码块中一致地更改标识符时报告。
请参阅我们的http://www.semanticdesigns.com/Products/SmartDifferencer/index.html, 以了解一种基于语法树的比较引擎,该引擎可与多种语言配合使用,可以进行上述近似处理。
EDIT 2010年1月:适用于C ++,C#,Java,PHP和COBOL的版本。该网站显示了其中大多数的具体示例。
编辑:2010年5月:添加了Python和JavaScript。
编辑2010年10月:添加了EGL。
编辑2010年11月:添加了VB6,VBScript,VB.net
您正在寻找的是“ tree diff”。事实证明,这比简单的面向行的文本差异要难得多,后者实际上只是两个平面序列的比较。
“ 细粒度的XML结构比较方法 ”部分总结为:
我们的理论研究和实验评估表明,相对于现有替代方法,该方法在结构上具有相似性,同时具有相同的时间复杂度(O(N ^ 2))
(强调我的)
确实,如果您正在寻找更多有关树差异的示例,我建议您专注于XML,因为这一直在推动该领域的实际发展。
我自己的项目的无耻插件:
HTML Tree Diff对使用python编写的xml和html文档进行结构感知比较。
解决方案将基于每种语言。也就是说,除非它设计的插件体系结构将许多代码解析成一棵树,并将语义与特定于语言的插件进行比较,否则将很难支持多种语言。您对使用这种工具感兴趣的语言是什么。就个人而言,我会喜欢C#。
对于C#,在Reflector中有一个程序集差异加载项,但它仅对IL而不是C#进行差异。
一家名为Zynamics的公司提供了二进制级别的语义差异工具。它使用称为REIL的元汇编语言对二进制的2个版本进行图论分析,并生成彩色编码图以说明它们之间的差异。我不确定价格,但是我怀疑它是免费的。
Pretty Diff会最小化每个输入以删除注释和不必要的空格,然后在diff算法之前美化代码。无论如何,我想不出比这更多的代码语义了。并且,其编写的JavaScript使其可以直接在浏览器中运行。