1

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

例如来自以下 c 文件

int mynum = 12;

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

我想回归一些 Python 魔法

["mynum", "timers"]

如何做到这一点(以一种不特定于良好 c 格式的方式),Python 的魔力是什么?

注意:这是用于解析仅包含变量声明的文件。

4

2 回答 2

2

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

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

如果您只需要变量名称,请解析 XML for tagVariable并提取属性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"/>
于 2013-02-07T13:59:03.917 回答
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'd 并且你也有struct(和union?)它们也可以这样工作......更不用说任何一点,你可以#include "anyfile.c"——作为一个程序员,这将是一件非常讨厌的事情,但这是可能的。我认为c99你也可以在任何你想要的地方声明变量(例如在宏中)。你也想收拾那些吗?换句话说,要正确执行此操作,您需要一个完整的 c 解析器来为您完成繁重的工作

于 2013-02-07T13:55:12.433 回答