如何从Python中的c文件中获取变量名列表

时间:2013-02-07 13:50:20

标签: python parsing

我有一个c文件,想要创建一个定义的所有变量名列表 - 使用Python。

E.g。来自以下c文件

int mynum = 12;

// Timers
VAR_IN_SECTION(task_timers, .mem_layout)
timers_t timers[DSP_NUM_TASK_TIMERS];

我想要一些Python魔法返回

["mynum", "timers"]

怎么可能这样做(以一种不是特定于良好的c格式化的方式),Python魔术会是什么?

注意:这是为了解析一个只包含变量声明的文件。

2 个答案:

答案 0 :(得分:2)

您可以使用GCC-XML工具将C源文件的声明转换为XML。然后,您可以使用Python XML解析器(例如lxml.etree)来解析结果。

GCC-XML输出XML结构相当容易解析。它将为您提供变量声明(标记:<Variable>)和类型定义(多个标记,例如<FundamentalType><Pointer><Struct>等...)。您需要执行一些处理来递归地派生实际类型(例如Pointer引用一个子类型 - 指向类型),但它会为您提供所需的一切,如果你'我愿意花一些时间在上面。

如果您只想要变量名称,请解析标记Variable的XML并提取属性name

奇怪的是,我正在构建一个这样的解析器作为项目的一部分。我(还)允许分发,但我希望它最终会被开源发布。

示例:

typedef int* myintptr;

myintptr p;   

生成如下XML:

<Variable id="_3" name="p" type="_64" context="_1" location="f0:5" file="f0" line="5"/>
<Typedef id="_64" name="myintptr" type="_63" context="_1" location="f0:3" file="f0" line="3"/>
<PointerType id="_63" type="_156" size="64" align="64"/>
<FundamentalType id="_156" name="int" size="32" align="32"/>

答案 1 :(得分:1)

这适用于您提供的示例输入文件,但我很确定在我说这通常适用于c语法之前我需要更多的测试:

>>> s = """int mynum = 12;
... 
... // Timers
... VAR_IN_SECTION(task_timers, .mem_layout)
... timers_t timers[DSP_NUM_TASK_TIMERS];"""
>>>
>>> import re
>>> re.findall(r'\w+[ \t]+(\w+)',s)
['mynum', 'timers']

上面发布的答案不会指出:

int *p;

要选择那些,可能会稍微调整一下正则表达式:

>>> re.findall(r'\w+[ \t]+(?:\*\s*)?(\w+)',s)
['mynum', 'timers', 'p']

使用C,您无法查找各种类型(intfloatdoublechar ...),因为事情总是可以使用typedef你也有struct(和union?)也是这样的...... 更不用说任何一点,你可以#include "anyfile.c" - 作为一个程序员,这将是一个非常讨厌的事情,但它是可能的。我认为使用c99你也可以在任何你想要的地方声明变量(例如在宏中)。你想要选择那些吗?换句话说,要正确地执行此操作,您需要一个完整的c-parser来为您完成繁重的工作