【问题标题】:Semantic Diff Utilities [closed]语义差异实用程序[关闭]
【发布时间】:2010-10-06 02:47:54
【问题描述】:

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

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

我认为这种类型的语义信息实际上是用户在比较代码时所寻找的,并且应该是下一代编程工具的目标。可用工具中有这方面的例子吗?

【问题讨论】:

  • 看起来已经对树编辑距离进行了一些研究。将其应用于 AST 似乎是首先要尝试的事情。 (如果有人想尝试写这种东西。)
  • 我不确定它是否真的有用。像您提到的差异比阅读更容易看到,特别是如果您有一个工具突出显示行内的差异。识别某些代码是否刚刚被移动而不改变的能力会更容易和更有用,恕我直言!
  • @UncleZeiv 我希望该功能自然会遵循该工具的性质。此外,如果有人通过并更改了花括号或缩进样式,或者重新排列文件以便对静态方法进行分组等,它将能够检测到没有任何更改。
  • 我现在在 Visual Studio 中需要这个。强迫团队中的开发人员使用相同的格式结构来促进差异是一种倒退的想法。代码应该在签入时按照某种标准进行格式化,并且任何时候开发人员打开文件时,都应该按照他们的喜好对其进行格式化。我很震惊这种想法在这一点上没有得到更广泛的传播。
  • 恕我直言,这是一个很好的话题。如果您同意这一点,请投票“重新开放”

标签: language-agnostic diff semantics


【解决方案1】:

我们开发了一种工具,可以精确地处理这种情况。检查http://www.semanticmerge.com

它基于代码结构进行合并(和差异),而不是使用基于文本的算法,这基本上允许您处理以下情况,涉及强重构。它还能够呈现差异和合并冲突,如下所示:

并且不会对被移动的文本块感到困惑,因为它首先解析,它能够基于每个方法(实际上是每个元素)显示冲突。像以前这样的案例甚至不需要手动解决冲突。

这是一个语言感知的合并工具,很高兴终于能够回答这个 SO 问题 :-)

【讨论】:

  • 可以和SVN集成吗?
  • 但是,Linux 和 Mac 版本是古老的。
【解决方案2】:

Eclipse 有这个功能很久了。它被称为“结构比较”,非常好。这是 Java 的示例屏幕截图,然后是 XML 文件的示例屏幕截图:

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

【讨论】:

  • 结构比较是否允许您像其他源代码管理合并编辑器一样合并更改? IE。将此方法从这个版本复制到另一个版本。
  • 是的,当您选择更改或差异(在上部或下部窗格中)时,工具栏按钮(显示在屏幕截图中)为您提供从左到右复制更改的选项或反之亦然。
  • 不幸的是,屏幕截图不再显示在您的(最高支持和接受!)答案中。你能再提交一次吗?
  • @blubb 感谢您通知我。我已经用 Java 比较器图像纠正了错误。我会尽快为 XML 结构比较器添加屏幕截图。
  • 这适用于 Java 以外的语言吗?
【解决方案3】:

要做好“语义比较”,需要比较语法树 语言,并考虑符号的含义。一个真的 好的语义差异会理解语言语义,并实现 当一个代码块在功能上与另一个代码块相同时。去 到目前为止需要一个定理证明器,虽然这将是非常 很可爱,目前还不能作为真正的工具使用。

一个可行的近似方法是简单地比较语法树,然后报告 插入、删除、移动或更改的结构的变化。 有点接近“语义比较”,可以报告 当标识符在代码块中一致更改时。

请参阅我们的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

【讨论】:

  • 嗨,Ira,你发表过一篇关于你的 diff 算法的论文吗?我很难找到树编辑距离差异文献。谢谢,特伦斯。
  • 更具体地说,寻找 diff3 而不是普通的 diff2
  • @Terence:我们的 diff 算法不存在任何出版物。这是一个 Levenstein 最小距离计算,使用后缀树来识别相等的子树,并使用一些 huerstics 来处理重命名。 IIRC,Yang 在 Software Practice and Experience 中有一篇关于此的论文。我们和杨的是 diff2,而不是 diff3。
  • @IraBaxter 该链接目前已损坏,从谷歌链接打开时网站似乎已关闭。
  • 网站已备份,链接应该没问题。
【解决方案4】:

您正在摸索的是“树差异”。事实证明,这比简单的面向行的文本差异(实际上只是两个平面序列的比较)要困难得多。

A Fine-Grained XML Structural Comparison Approach”结尾部分是:

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

(强调我的)

确实,如果您正在寻找更多关于树差异的示例,我建议您关注 XML,因为这一直在推动该领域的实际发展。

【讨论】:

  • 感谢您的链接。我可以想到几种不同的方法来实现语义差异工具,你是对的——大多数都可以抽象为“树差异”。甚至可能需要将更复杂的情况抽象为“图差异”。
  • 是的。 IBM 的 Rational Modeler(基于 eclipse 构建)尝试使用 UML 模型(以图形方式显示两个模型之间的差异)来做到这一点。我不能评论结果的有用性,因为我不经常使用它。
  • 我同意 XML 是一个很好的起点,因为您可以简单地提出模式来表示其他结构(例如 java 代码),并使用基于 XML 的 tree-diff实现代码差异。
  • "do this" => 做一些类似于“graph diff”的事情。
  • 查看semdesigns.com/Products/SmartDifferencer/index.html,了解适用于多种语言的基于语法树的比较引擎。
【解决方案5】:

我自己项目的无耻插件:

HTML Tree Diff 对 xml 和 html 文档进行结构感知比较,用 python 编写。

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

【讨论】:

    【解决方案6】:

    解决方案将基于每种语言。 IE。除非它采用插件架构设计,将大量代码解析推迟到树中,并且与特定语言的插件进行语义比较,否则将很难支持多种语言。您对拥有这样的工具感兴趣的语言是什么。就我个人而言,我喜欢 C# 的一个。

    对于 C#,Reflector 有一个程序集差异插件,但它只对 IL 而非 C# 进行差异。

    您可以下载 diff 插件 here [zip] 或前往 codeplex 网站 here 上的项目。

    【讨论】:

    • 请参阅semdesigns.com/Products/SmartDifferencer/index.html,了解基于语法树的比较引擎,它适用于多种语言,完全使用语言插件样式。尚未发布,但 C# 版本非常接近。
    • 2010 年 1 月:C# Smart Differencer 发布。
    【解决方案7】:

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

    【讨论】:

    【解决方案8】:

    http://prettydiff.com/

    Pretty Diff 缩小每个输入以删除 cmets 和不必要的空白,然后在 diff 算法之前美化代码。无论如何,我想不出比这更多的代码语义。而且,它编写的 JavaScript 可以直接在浏览器中运行。

    【讨论】:

    • 那你的想象力有限!交换文件中两个方法的位置同时保持它们不变呢?重构呢?
    • (你不能以这种方式在 Java 中交换数据声明,并且由于初始化程序的原因仍然具有等价性;我认为 C# 也有类似的问题)。如果您选择纯语义差异,那么您正在尝试解决图灵机等价问题。比纯文本匹配做得更好,比图灵不可能做得更好。
    • @IraBaxter 该工具在概念上显然只会显示为实际上等效的等效事物。如果编码正确,则不会出现您提到的问题类型。
    • “正确编码”意味着如果您想要终极工具,则证明算法等价。算法等价证明通常是图灵难的,所以在实践中你不会得到这样的工具。您可能会得到一个工具,它可以处理 some 等价,而不仅仅是语法更改。迄今为止,我还没有看到有人尝试构建这样的工具。
    猜你喜欢
    • 2023-03-09
    • 2013-09-04
    • 2017-03-16
    • 2011-06-11
    • 2010-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-22
    相关资源
    最近更新 更多