首页 > 解决方案 > 是否可以一次性在线确定对象的类型,包括宏?

问题描述

我有一个非常简单的解析器,它提供了一小部分 C 语言;它着眼于一个格式良好的翻译单元,并且通过一次在线和在线,确定全局符号和类型(函数、结构、联合、变量),如果不是试图欺骗它的话。struct但是,在此示例中,我无法确定它是一个函数还是一个函数,

#define CAT_(x, y) x ## y
#define CAT(x, y) CAT_(x, y)
#define F_(thing) CAT(foo, thing)

static struct F_(widget) { int i; }

F_(widget);

static struct F_(widget) a(void) { int i;
    return i = 42, F_(widget).i = i, F_(widget); }

int main(void) {
    a();
    return 0;
}

它假设括号是一个函数并以这种方式解析,

[ID<stati>, ID<struc>, ID<F_>, LPAR<(>, ID<widge>, RPAR<)>, LBRA<{>, RBRA<}>].
[ID<F_>, LPAR<(>, ID<widge>, RPAR<)>, SEMI<;>].
[ID<stati>, ID<struc>, ID<F_>, LPAR<(>, ID<widge>, RPAR<)>, ID<a>, LPAR<(>, ID<void>, RPAR<)>, LBRA<{>, RBRA<}>].
[ID<int>, ID<main>, LPAR<(>, ID<void>, RPAR<)>, LBRA<{>, RBRA<}>].

实际上,它认为顶部的函数实际上是一个struct声明,并且应该将前两个连接起来。识别这一点的最简单方法是什么?

标签: cparsing

解决方案


如评论中所述,如果您希望能够处理预处理器宏,则需要实现(或借用)预处理器。

编写预处理器主要涉及接受 C 标准中的正式描述,但在其他方面并不是特别具有挑战性。它可以在线完成,将生成的令牌流输入解析器,因此它实际上不需要第二遍。

(这取决于您如何定义“通过”我想,但在我的使用中,一次性解析器只读取一次输入,而不创建和重新读取临时文件。这绝对是可行的。)


推荐阅读