我正在维护/开发一个家庭作业测试平台。它主要是自动的。我现在需要添加的是代码分析。我需要检查特定构造的代码。
例如:
该文件是否
main.cpp
包含一个以user
const 方法 命名的类get_name()
?
是否有一些工具可以让我做这样的事情(理想的是可以编写脚本的东西)。仅限 Linux。
我正在维护/开发一个家庭作业测试平台。它主要是自动的。我现在需要添加的是代码分析。我需要检查特定构造的代码。
例如:
该文件是否
main.cpp
包含一个以user
const 方法 命名的类get_name()
?
是否有一些工具可以让我做这样的事情(理想的是可以编写脚本的东西)。仅限 Linux。
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
您可能可以毫不费力地将使用GCC-XML 框架的东西拼凑起来。
我从 Mozilla 发现了 dehydra 工具。它似乎主要是为内部目的而编写的,但它可能正是我想要的。
https://developer.mozilla.org/En/Dehydra/Using_Dehydra
编辑:脱水很棒。它缺少一些次要功能,例如确定 const 方法,但其他方面都很棒。
如果要进行任意代码分析,则需要任意解析/匹配/等。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 下运行。