7

我正在维护/开发一个家庭作业测试平台。它主要是自动的。我现在需要添加的是代码分析。我需要检查特定构造的代码。

例如:

该文件是否main.cpp包含一个以userconst 方法 命名的类get_name()

是否有一些工具可以让我做这样的事情(理想的是可以编写脚本的东西)。仅限 Linux。

4

5 回答 5

3

一种可能是通过GCC运行代码并使用GCC-XML扩展来生成程序内部结构的 XML 描述。然后,您可以使用您最喜欢的 XML 库来解析文档,或者如果您需要做的只是将其显示为 HTML 或其他方式,则对其应用 XSLT。

于 2010-09-14T15:59:53.460 回答
1

How does this apply to C? :)

Does the file main.cpp contain a class named user with a const method get_name()?

Create another file (test.cpp) with

void test(void) {
  const user x;
  x.get_name();
}

compile test.cpp and main.cpp together. If there's an error (exit code != 0) then NO!, the file main.cpp does not define a (public) class named user with the specific method.

Caveat: I know no C++, so excuse any major (or minor) errors in the above.


Edit script added

#! /bin/sh

cat main.c test.c > 3710532.c
if gcc 3710532.c > /dev/null 2>&1
then echo OK
else echo BZZZT
fi
rm 3710532.c

I don't have a ready-to-use C++ compiler installed on this machine I'm on, so my test was with a C compiler and C files. My compiler didn't "work with" gcc -combine main.c test.c so I tweaked that part.

Running this script with a working combination of main.c and test.c outputs 'OK', otherwise it outputs 'BZZZT'.


For the tests I used this main.c

typedef int user;

int get_name(void) {
  return 0;
}

int main(void) {
  return 0;
}

and this test.c

void test(void) {
  const user x;
  get_name();
}

Sample run

$ ./3710532.sh
OK
于 2010-09-14T18:38:12.057 回答
1

您可能可以毫不费力地将使用GCC-XML 框架的东西拼凑起来。

于 2010-09-14T16:00:38.513 回答
0

我从 Mozilla 发现了 dehydra 工具。它似乎主要是为内部目的而编写的,但它可能正是我想要的。

https://developer.mozilla.org/En/Dehydra/Using_Dehydra

编辑:脱水很棒。它缺少一些次要功能,例如确定 const 方法,但其他方面都很棒。

于 2010-09-15T12:05:49.027 回答
-1

如果要进行任意代码分析,则需要任意解析/匹配/等。GCC-XML 将为您提供声明信息,但不提供方法的内容。

我们的DMS Software Reengineering Toolkit将提供与 GCC-XML 相同的抽象信息,但还包括由其C++ 前端支持的定义内容的完整详细信息(例如,方法主体信息) 。这将让您访问声明内容以检查您的学生计划。

DMS 为 AST、符号表和源模式匹配提供通用解析。C++ 前端提供完整的 C++ 解析、构建 C++ AST 和相应的符号信息。在那之后你要做什么取决于你,但你的例子似乎是关于寻找一个特定的模式。

您的示例的一半将由 C++ 的少数 DMS 源模式处理:

pattern is_correct_student_class(m:members):class =
  " class user { \m } ".

pattern is_correct_student_method_present(p:parameters,s:statements):method =
  " const  get_name(\p) { \s } "

(请原谅我的 C++ 语法,我不会写很多)它将匹配任何 AST,分别对应于命名的用户类和所需的 const 方法。引号是元引号,里面的东西是 C++ 语法,用转义符 \p、\m 和 \s 表示元变量 p、m 和 s,它们在语法上必须分别是参数列表、方法列表和语句列表为了匹配模式。参数列表等的定义是从 C++ 前端的 C++ 语法部分自动派生的。

另一半由调用 C++ 解析器和名称/类型解析器后执行的一些 DMS PARLANSE 代码实现:

   (define has_student_code (lamdba (function boolean [tree AST]))
      (AST:IsInTree tree
          (lambda (function boolean [tree1 AST]
              (&& (Registry:MatchPattern tree1 "is_correct_student_class")
                  (AST:IsInList (AST:GetNthGrammarChild tree1 4) ; the member list
                       (lambda (function boolean [tree2 AST]) 
                           (Registry:MatchPattern tree2 ; a member
                                 "is_correct_student_method_present")
                       )lambda
          )lambda
      )
   )define

采取了一些自由来简化演示。

这是一个非常简单的检查;您可以从 PARLANSE 代码访问符号表,以进行更复杂的检查是否有意义。

虽然 DMS 不能直接在 Linux 下运行,但它似乎可以在 Wine 下运行。

于 2010-09-14T23:59:35.510 回答