脱离上下文阅读问题标题可能会产生误导。让我先解释一下我要做什么。
我正在构建一个脚本,它将需要由我的学生编写的100个非常简单的C程序,并检查一些非常基本的属性,如。
- 他们是否声明了一个名为'x'的变量,它的类型是'int'等等
- 变量"z"的值是多少?
如果这是某种脚本编程语言,这可能会容易得多。我可以简单地使用include或eval,然后进行检查。
但是当涉及到C编程时,我会说这是非常困难的。我该怎么做呢?
您可以使用ANTLR来完成此操作。已经有一个C语法可以在ANTLR中使用,所以主要你要做的就是将代码传递到ANTLR中,然后遍历语法树寻找各种属性....
可以使用许多语言的ANTLR。虽然一开始看起来很吓人。
我看到了为GCC构建的树创建XML转储器的倡议,称为GCC - XML。给它命名为example1.cxx
文件,如
struct EmptyClass {};
int a_function(float f, EmptyClass e)
{
}
int main(void)
{
return 0;
}
你会回来的:
<?xml version="1.0"?>
<GCC_XML>
<Namespace id="_1" name="::" members="_2 _3 _4 "/>
<Function id="_2" name="main" returns="_5" context="_1" location="f0:8"/>
<Function id="_3" name="a_function" returns="_5" context="_1" location="f0:4">
<Argument name="f" type="_6"/>
<Argument name="e" type="_4"/>
</Function>
<Struct id="_4" name="EmptyClass" context="_1" location="f0:1" members="_7 _8 " bases=""/>
<FundamentalType id="_5" name="int"/>
<FundamentalType id="_6" name="float"/>
<Constructor id="_7" name="EmptyClass" context="_4" location="f0:1">
<Argument name="_ctor_arg" type="_9"/>
</Constructor>
<Constructor id="_8" name="EmptyClass" context="_4" location="f0:1"/>
<ReferenceType id="_9" type="_4c"/>
<File id="f0" name="example1.cxx"/>
</GCC_XML>
注意,它只适用于与c++兼容的C子集,并且官方项目不支持函数体的转储。我不知道非官方的努力取得了多大的进展:
http://www.djlauk.de/index.php/Projects/GccXmlFunctionBodies一个重要的区别是"检查"这些程序的意思。我假定您的意思不是在运行时实际编译/运行它们(这就是反射对我的意义),因为您不能从编译的程序检查它们的程序结构。
这意味着您将对源文件进行文本处理,虽然这在几乎所有脚本语言中都要容易得多,但在C中并不那么糟糕:
-
弄清楚如何获得要处理的所有文件的列表。要么将所有文件名放在索引文件中,然后遍历该文件,要么使用
readdir
或最好使用库(Boost)为您获取文件列表。 -
对于每个文件,打开它并读取每一行(谷歌,这是微不足道的)
-
对于每一行,根据您的规则进行检查,并收集必要的结果。
-
将结果存储在数组中,或将其写入文件等
编辑-如果你想检查你的学生的程序是否运行(aka,编译/运行它们在运行时),你可能不得不execve
关闭一些gcc调用(如果你想编译),然后再次运行程序。但是,execve
只会告诉您命令是否失败。从其他程序获取输出意味着使用popen
打开管道。如果你发现自己已经准备好这样做了,那就回头吧,你已经走得太远了。
语言内部的反射总是受到语言设计者的限制(C语言的设计者根本不允许任何反射)。如果您使用的工具可以从语言外部检查语言的任何部分,那么您就不会受到语言设计者想象的限制。(目前所有带有反射的语言都限制了你用这种语言写代码所能学到的东西。在我看来,这是一个愚蠢的限制。
分析程序的方法是让代理从外部理解编程语言,并且没有任何这样的限制。请参阅我们的DMS软件再造工具包,了解可以提供最终程序检查的系统。使用它的C前端,你可以用可靠的方式问任何关于C源代码的问题。
你问的具体问题可以很容易地由DMS和它的C前端回答(关于Z值的问题可能很难;你在推理图灵机)