c - 是否可以一次性在线确定对象的类型,包括宏?
问题描述
我有一个非常简单的解析器,它提供了一小部分 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
声明,并且应该将前两个连接起来。识别这一点的最简单方法是什么?
- 两遍,模拟宏替换中实际发生的情况;我必须构建 C 预处理器的一个子集;
- 像C lexer hack一样,除了宏;
- 以分号结尾的回溯;这似乎很难;
- 以某种方式在一开始就认识到差异,(可能需要我添加
struct
到我的符号表中。)
解决方案
如评论中所述,如果您希望能够处理预处理器宏,则需要实现(或借用)预处理器。
编写预处理器主要涉及接受 C 标准中的正式描述,但在其他方面并不是特别具有挑战性。它可以在线完成,将生成的令牌流输入解析器,因此它实际上不需要第二遍。
(这取决于您如何定义“通过”我想,但在我的使用中,一次性解析器只读取一次输入,而不创建和重新读取临时文件。这绝对是可行的。)
推荐阅读
- java - Jboss eap 6.4 到 Wildfly 14/18 迁移
- python - Python 3.7 版中是否存在 Isinstance?
- docker - 如何升级 pod securityContext runAsUser: 1010 的 kubernetes 容器权限
- javascript - 完整的日历未显示在 Web 表单上;脚本未运行
- angular - Angular 9 升级在编译期间导致 @types 错误
- gcc - 未对齐的向量指针异常 (AVX512)
- node.js - npm 错误!在“...ttps://registry.npmjs”附近解析时 JSON 输入意外结束
- typescript - 通过 LSP 扩展中的 CodeLens 请求发送参数
- scala - 未从 Web 客户端发送或接收到 Web 套接字的消息
- r-markdown - Rmarkdown 中的引用:使用 .bib 文件中的标题大写