我有一个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魔术会是什么?
注意:这是为了解析一个只包含变量声明的文件。
答案 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,您无法查找各种类型(int
,float
,double
,char
...),因为事情总是可以使用typedef你也有struct
(和union
?)也是这样的......
更不用说任何一点,你可以#include "anyfile.c"
- 作为一个程序员,这将是一个非常讨厌的事情,但它是可能的。我认为使用c99
你也可以在任何你想要的地方声明变量(例如在宏中)。你想要选择那些吗?换句话说,要正确地执行此操作,您需要一个完整的c-parser来为您完成繁重的工作