抽象解释器如何工作?

时间:2011-01-29 07:49:10

标签: c interpreter abstract

我正在尝试为C构建一个抽象解释器。可能不是针对整个语法而是针对它的一个子集。我之前曾问过使用什么语言。在我继续进行之前,我想知道这种抽象解释是如何工作的?

我已经浏览了Wiki链接和讲义说明链接。我理解其背后的理论基础和理论。我的分析得到了解决。我完全无法理解的部分是如何解释代码。也就是说,我有初始代码。我现在已经预处理了。我还对我的分析所需的代码执行了一些规范化。现在,当我继续执行代码时,如何逐行执行代码并从中提取数据? (请告诉我这是不可能的。或者有一些方法可以正确执行实现我目标的程序)。我正在寻找收集动态分配空间的内存地址,函数调用的返回地址等信息。

我之前曾建议CIL,CIL主要是一个转换工具,将代码转换为一些规范化的形式,处理许多异常,但我无法得到任何与我的问题有关的信息。

我的问题是如何逐行提取信息,哪种语言更可取?命令式语言或函数式语言?我一直在谷歌搜索有关这方面的信息,但没有用。任何链接也非常感谢。感谢。

编辑:我仍然有些疑惑。我得到了我们尝试构建虚拟环境的部分。让我解释一下我想要做什么,这样它将有助于讨论。我基本上尝试做指针分析,主要集中在指针算法上。现在假设我有一个整数指针,我做一个指针运算,然后我不能确定指针是否仍指向有效数据。

根据您的说法,我理解我们需要为变量分配空格,但值是什么。如果我有类似下面的内容

int a=10;
int *p = &a;
p = p+4;

这里a和常数'4'的值是已知的。如果我从用户或文件中获取价值该怎么办?在这种情况下,我需要执行实际的程序。与此同时,我需要捕获地址等数据。下面,

int *p =(int *) malloc (sizeof(int));
*p= 15;
cout<<*p;
p = p+ino//some user input value;
cout<<*p;

所以基本上代码必须执行但后来解决方案的一部分听起来更像解析C文件。如果我错了,请纠正我。

3 个答案:

答案 0 :(得分:3)

假设你真的在谈论抽象解释而不仅仅是解释C ......

抽象解释依赖于两个方面 - 抽象域,有限高度点阵和抽象语义,其中将行的语义应用于域之前的行中的值必须在域中生成新值,即相同的高度或更高。

即。如果您的域名为{1,2,3,4}并且输入为{1,2,3},则唯一有效的输出为{1,2,3}{1,2,3,4}(假设通常设置排序)

然后,您可以在每一行上执行定点递归,并使用行存储语义的输出,并使用函数定义存储每个函数末尾的语义。你如何选择领域并解释你最终得到的集合取决于你想要做的分析,但这就是我理解的大纲...

我必须说我是这方面的专家,但我的一些研究同事过去曾和我谈过这个问题,这就是我的理解......

此外,您可以轻松地向后运行分析 - 从函数结束开始并继续前进,这对某些类型的分析更合适......

答案 1 :(得分:2)

CIL能够执行SSA-transform。 SSA表单中的程序非常容易reason about并且部分评估 - 您只需要替换命名值,忽略或合并来自 phi - 节点的值。因此,为了将CIL转换为适当的抽象解释器,您只需在SSA(已经存在)之后添加几个转换。或者,您可以在Clang生成的LLVM IR之上进行此类转换。

答案 2 :(得分:1)

从你提出问题的方式来看,你所谈论的似乎是解释,而不是抽象解释。解释只是意味着获取C代码并自己运行它,在您的情况下从运行时发生的事情中提取一些信息。抽象解释是指一种静态分析过程,在这种过程中,您尝试理解程序能够做什么,可能出于优化目的,或者可能试图证明正确性或缺少错误。当然,我可能完全错了,在这种情况下你可以忽略这个答案。

如果您正在尝试编写解释器,那么您可能需要设置一个运行程序的虚拟执行环境。也就是说,您可能希望设置一个巨大的字节数组作为程序的内存,并且需要维护自己的堆栈指针和堆分配器。然后,您可以逐行执行该程序,并根据您正在执行的特定代码行修改此环境的状态。例如,执行类似

的语句
int a;

可以通过将堆栈指针增加四个字节来运行,同时运行类似

的操作
a = 137;

将查找a引用的全局内存数组的哪个部分,然后使用137的四字节值覆盖字节。从这一点开始,跟踪执行期间发生的事情应该相对简单 - 在解释器执行任何特定语句或评估表达式之前,您可以记录任何相关的详细信息。

请注意,这并不容易。你将不得不手动分配和清除堆栈帧,维护程序计数器等。但是,这听起来很有趣,祝你好运!