使用Python制作预处理器

时间:2013-06-05 12:45:28

标签: python c preprocessor c-preprocessor

我基本上需要用Python编写一个C预处理器,我一直在搜索,因为我需要完全自定义我的代码并完全了解正在发生的事情,我最好自己编写。

这就是我的位置:我首先解析一些头文件(.h)来查找#define关键字并使用所有已创建的指令构建一个字典(其值为一个)。然后我需要解析源文件(.c),具体取决于我之前找到的指令。 我现在用来检查代码是否需要处理的机制如下:我获取我的所有定义的名称及其值并执行exec("define_name = define_value")(未指定时值为'1')。然后解决#if defined DEFINE_1 || defined DEFINE_2 && (DEFINE_3 == 10) ....之类的条件我删除了C预处理器关键字,使它们成为Python样式,这将产生DEFINE_1 or defined DEFINE_2 and (DEFINE_3 == 10)

我最后在该字符串上使用eval(...)来查找结果。

问题是我想知道是否需要使用exec / eval并且许多人不愿意使用它们,是否有更好的解决方案?

1 个答案:

答案 0 :(得分:2)

当然不需要exec(),不应该使用eval()。我甚至不确定你期望它做什么,因为它会调用shell来设置一个只存在于子shell中的变量。

一般来说,你应该避免#define陈述,而且很少做正确的事。

那么,你能做什么?

1)首先,因为程序可以写成一个语句覆盖前一个语句,你不能预处理.h文件(或者甚至假设#define foo 1 #if foo == 1 this line is true! #endif #define foo 0 你正在寻找因为首先只有.h文件)并让它工作。考虑一下:

#include

如果你预先处理你将“foo”设置为1,然后设置为0,然后再评估#if。你做不到......

2)更常见的事情是编写一个逐行扫描的解析器,一次处理一行的内容。这样你甚至可以编写一个递归函数来处理# ... file opening not shown ... for line in file: includematch = re.match("#include\\s+\\"(.*)\\"", line) if match: # deal with an include statement by calling a function to process it read_file(includematch.group(1), definedict) definematch = re.match("#define\\s+(\\w+)\\s+(.*)") if definematch: # deal with define statements by saving it in a dict definedict[match.group(1)] = definedict[match.group(2)] #.... 语句,这样你就可以从.c文件开始,让它拉入正在使用的正确的头文件,而不是要求以其他方式指定它们。

最后,你应该得到类似的东西(在一个名为“read_file”的函数中):

{{1}}

显然,如果我向你展示了整个解决方案(以上几乎不是漂亮的代码,但是为了显示目的它很简洁)我会为你解决你的问题(作业?)。但是,上面是一个更好的方法来构建整个事物而不是你前进的道路。