Pycparser 无法处理预处理代码

Ara*_*uma 2 preprocessor python-2.7 pycparser

我需要在预处理的 C 代码('gcc -E' 产生的结果)上使用 pycparser。但是,我目前遇到了无法理解或解决的问题。

我正在使用提供的示例 year2.c 和 func_defs.py,我对其进行了修改以使用各种预处理器和假库,但无济于事。也许你们中的一些人可以研究一下,看看你是否可以重现/解决这个问题。我将附加所有必要的代码。

错误是使用 year2.c(常规示例文件)和 year2.i('gcc -E' 输出)生成的。后者没有可用的结果,而前者同时使用预处理器/fakelib 变体。

我创建了一个包含所有相关错误的 bitbucket 存储库、使用的脚本(尽管只是它的最后一个变体)以及 year2.c 和 year2.i 文件。

错误和样本回购

谢谢你的时间。

ric*_*ici 5

你得到的错误是:

pycparser.plyparser.ParseError: /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h:40:27: before: __gnuc_va_list
Run Code Online (Sandbox Code Playgroud)

指示导致错误的行 ( stdarg.h:40):

typedef __builtin_va_list __gnuc_va_list;
Run Code Online (Sandbox Code Playgroud)

在 gcc 中,__builtin_va_list顾名思义,是内置于编译器中的。因此,不需要(或允许)该类型的声明。

C 编译器使用基于符号表的技术来解析类型名是很常见的,因为如果您无法区分类型名和另一个标识符,语法中就会存在许多歧义。这样的解析器将假定未声明的标识符不是类型名,如果__builtin_va_list不是类型名,那typedef就是语法错误。

所以我想你使用的 pyparser 语法不知道 gcc 内置类型(为什么应该知道?)。

您的 fakelib 似乎包含相同的头文件。这并不奇怪,因为它很难伪造stdarg.h;虽然从技术上讲是一个库头文件,但它是编译器必须提供的一小部分头文件的一部分,即使在独立(无标准库)实现中:<float.h>, <iso646.h>, <limits.h>, <stdalign.h>, <stdarg.h>, <stdbool.h>, <stddef.h>, <stdint.h>,和 <stdnoreturn.h>(C11 标准,第 4 条,第 6 段)。这些必须由编译器实现,因为外部库无法充分了解已编译代码的性质以正确定义它们。

根据您对 pyparsed 输出的要求,您可以通过包含 的定义来为 pyparser 解决此问题__builtin_va_list,例如:

typedef struct __builtin_va_list { } __builtin_va_list;
Run Code Online (Sandbox Code Playgroud)

__builtin_va_list不是唯一的内置 gcc 数据类型,尽管您可能不会遇到其他类型。因此,您可能需要多次迭代此解决方案,直到实现您想要实现的目标。