繁体   English   中英

解析C文件而不预处理它

[英]Parsing C files without preprocessing it

我想对C文件运行简单的分析(例如,如果你用INT_TYPE作为参数调用foo宏,然后将响应转换为int* ),我不想预处理文件,我只是想解析它(这样,例如,我将有正确的行号)。

即,我想得到

#include <a.h>

#define FOO(f)

int f() {FOO(1);}

一个令牌列表

<include_directive value="a.h"/>
<macro name="FOO"><param name="f"/><result/></macro>
<function name="f">
    <return>int</return>
    <body>
        <macro_call name="FOO"><param>1</param></macro_call>
    </body>
</function>

无需设置包含路径等

有没有预先存在的解析器呢? 我知道的所有解析器都假设C是经过预处理的。 我想访问宏和实际包含指令。

我们的C前端可以解析包含preprocesser元素的代码,可以在相当程度上做到这一点,并且仍然构建一个可用的AST。 (是的,解析树具有精确的文件/行/列号信息)。

有许多限制,允许它处理大多数代码。 在少数情况下,它无法处理,通常是对源文件的一个小的,简单的更改,给出等效的代码解决了问题。

这是一套粗略的规则和限制:

  • #includes和#defines可以出现在声明或语句可以发生的任何地方,但不能出现在语句的中间。 这些很少引起问题。
  • 宏调用可以发生在表达式中发生函数调用的地方,或者可以不用分号代替语句。 跨越非格式良好的块的宏调用处理不好(任何人都感到惊讶?)。 后者偶尔发生但很少发生,需要手动修改。 OP的“j(v,oid)*”的例子是有问题的,但这在代码中很少见。
  • #if ... #endif必须包含主要语言概念(非终结符) (常量,表达式,语句,声明,函数)或此类实体的序列,或围绕某些非格式良好但常见的惯用语,例如if (exp){ 条件的每个臂必须包含与其他臂相同类型的句法结构。 #if缠绕随机文本作为坏评论是有问题的,但通过做出真正的评论很容易在源中修复。 如果不满足这些条件,则需要修改原始源代码,通常是移动#if #elsif #else #end几个标记。

根据我们的经验,人们可以在几个小时内修改50,000行的代码库来解决这些问题。 虽然这看起来很烦人(而且确实如此),但替代方案是根本无法解析源代码,这比烦人的要糟糕得多。

您还需要的不仅仅是解析器。 请参阅解析后的生活 ,了解成功获取解析树后会发生什么。 我们在构建符号表方面做了一些额外的工作,其中声明是使用嵌入它们的预处理器上下文记录的,从而使类型检查能够包含预处理器条件。

你可以看看这个ANTLR语法 但是,您必须为预处理程序令牌添加规则。

您可以通过编写自己的解析并忽略宏扩展来处理您的具体示例。

因为FOO(1)本身可以解释为函数调用。

但是,当考虑更多情况时,解析器要困难得多。 您可以参考PDF链接以查找更多信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM