源代码逻辑评估

时间:2015-03-25 11:56:45

标签: parsing token grammar abstract-syntax-tree

我获得了一段代码(例如,用Java编写的一个名为bubbleSort()的函数)。我怎么能,或者更确切地说,我的程序,告诉一个给定的源代码是否以正确的方式实现特定的排序算法(例如,使用bubble方法)?

我可以通过分析函数签名来强制用户提供合法的函数:确保参数和返回值是整数数组。但我不知道如何确定算法逻辑正在以正确的方式完成。输入代码可以正确排序值,但不能在上述冒泡方法中排序。我的程序怎么能辨别出来?我确实意识到会涉及很多代码解析,但也许还有其他我应该知道的东西。

我希望我有点清楚。

如果有人能指出我正确的方向或提出如何解决这个问题的建议,我会很感激。也许有一些经过测试的方法可以简化程序逻辑的评估。

1 个答案:

答案 0 :(得分:1)

一般情况下,由于暂停问题,您无法执行此操作。你甚至无法决定该函数是否会停止("返回")。

实际上,还有更多的希望。如果您正在寻找冒泡排序,您可以决定它有多少部分:

  • 具有部分顺序的待分类数据类型
  • 具有单个实例变量A("数组")
  • 的容器数据类型C.
  • 包含待排序数据
  • 用于访问具有部分订单的容器的密钥类型K("数组索引") 使得容器[K]是S型
  • 使用密钥A和密钥B比较容器的两个成员 这样A< B根据关键的偏序,即确定 如果容器[B]>容器A
  • 对容器[A],容器[B]和类型S的某些变量T进行交换操作,这是条件性地依赖于比较
  • 一个环绕容器的循环,根据K
  • 上的部分顺序枚举键

您可以构建一些代码,在源代码中找到这些证据中的每一个,如果您找到所有这些代码,则声称您有冒泡冒号的证据。

具体而言,您需要标准的程序分析机制:

  • 解析源代码并构建抽象语法树
  • 构建符号表(ST),知道使用它的每个标识符的类型
  • 构造一个控制流图(CFG),以便检查各种识别的位是否以适当的顺序出现
  • 构建数据流图(DFG),以便您可以确定在算法的一部分中识别的值正确地流向另一部分

[那是很多机器才开始]

从这里开始,你可以编写特殊的代码程序代码来爬过AST,ST,CFG,DFG,以及#34;识别"每个部分。这可能会非常混乱,因为每个识别器都会检查这些结构以获得其位的证据。但是,你可以做到。

这很麻烦,而且很有趣,所以有些工具可以做很多事情。

我们的DMS软件再造工具包就是其中之一。 DMS已经包含了对多种语言进行标准程序分析的所有机制。 DMS还具有数据流模式匹配语言,灵感来自Rich and Water's 1980's "Programmer's Apprentice" ideas

使用DMS,您可以大致像这样(未经测试)表达这个特殊问题:

 dataflow pattern domain C;

 dataflow pattern swap(in out v1:S, in out v2:S, T:S):statements =
    " \T = \v1;
      \v1 = \v2;
      \v2 = \T;";

 dataflow pattern conditional_swap(in out v1:S, in out v2:S,T:S):statements=
     " if (\v1 > \v2)
          \swap(\v1,\v2,\T);"

 dataflow pattern container_access(inout container C, in key: K):expression
     = " \container.body[\K] ";

 dataflow pattern size(in container:C, out: integer):expression
     = " \container . size "

 dataflow pattern bubble_sort(in out container:C, k1: K, k2: K):function
     "  \k1 = \smallestK\(\);
        while (\k1<\size\(container\)) {
           \k2 = \next\(k1);
           while (\k2 <= \size\(container\) {
               \conditionalswap\(\container_access\(\container\,\k1\),
                                 \container_access\(\container\,\k2\)  \)
           }
       }
    ";

在每个模式中,您可以编写所选编程语言的具体语法(&#34;模式域&#34;),引用模式签名行中指定的数据流。一个子模式可以在另一个内部提到;必须通过命名它们将数据流传递给子模式或从子模式传递数据流。与&#34;普通的C&#34;不同,你必须明确地传递容器而不是隐式引用;这是因为我们对从模式中的一个地方流向另一个地方的实际价值感兴趣。 (仅仅因为代码中的两个位置使用相同的变量,并不意味着它们看到相同的值)。

鉴于这些定义,并要求&#34;匹配bubble_sort&#34;,DMS将访问DFG(与CFG / AST / ST相关联)以尝试匹配模式;在匹配的地方,它会将模式变量绑定到DFG条目。如果找不到所有内容的匹配项,则匹配失败。

为了完成匹配,上面的每个模式基本上都转换为它自己的DFG,然后使用所谓的子图同构测试将每个模式与代码的DFG进行匹配。为模式构建DFG需要机器的 lot :解析,名称解析,控制和数据流分析,应用于原始语言的代码片段,与各种模式元转义混合。子图同构是很容易的&#34;代码,但运行起来可能非常昂贵。保存DMS模式匹配器的原因是,大多数模式都有许多限制因素[技术要点:它们没有结节],每次尝试匹配都会很快失败,或者完全成功。

未显示,但通过单独定义各个位,可以提供替代实现,从而可以识别变体。

我们已经使用它来实现完全工厂控制模型提取工具,这些工具来自陶氏化学的真实工业工厂控制器,使用他们特有的Dowtran语言(意味着建筑解析器等,如上所述为Dowtran)。我们有这个原型的版本为C;数据流分析更难。