我基本上需要用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并且许多人不愿意使用它们,是否有更好的解决方案?
答案 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}}
显然,如果我向你展示了整个解决方案(以上几乎不是漂亮的代码,但是为了显示目的它很简洁)我会为你解决你的问题(作业?)。但是,上面是一个更好的方法来构建整个事物而不是你前进的道路。