繁体   English   中英

C++ 解析歧义:构造函数与带括号的声明符

[英]C++ parsing ambiguity: Constructor vs. parenthesized declarator

我正在尝试编写一个 yacc (menhir) 语法来解析 C++ 的一个非常简化的子集(没有模板,只允许没有 function 主体的标头......)并且我已经遇到了歧义。

typedef int B;

class A {
   A();     // (*)
   B(c)();  // (**)
};

case * 是构造函数,case ** 是带括号的声明符。 解析器如何区分? 我可以想象一些我说出的方法,但我想知道一个兼容的 c++ 解析器是如何做到的。 我也明白,我可能无法使用 yacc 解析 C++ 的实际子集,但我只想更好地了解发生了什么。 最后,也许我会切换到解析器组合器或其他东西。 另外,我应该注意我对链接 clang 的兴趣为零,因为我打算添加一些自定义语法。

解析 C++ 是令人沮丧的练习,因为 C++ 本质上不是上下文无关的。 您需要知道标识符是指模板、类型还是其他东西,C++ 中的名称解析也不是一项简单的任务。 例如,您可能必须实例化模板才能知道模板化 class 的成员是变量还是类型名。 (程序只需要对依赖类型中的名称使用typename 。)

因此,如果不考虑包含的 header 文件,您当然不能期望解析翻译单元。 (无论如何,你不能这样做,因为 header 文件可以定义一个宏,其扩展会以意想不到的方式改变语法。所以你需要一个预处理器。)

说了这么多,一切都没有丢失。 您可以使用 bison 生成 GLR 解析器,然后尝试编写自定义消歧函数。 如果消歧function需要知道一个名字是否是typedef,可以尝试在符号表中查找。 与经典的“lexer hack”方法不同,GLR 消歧发生在解析器中,因此它不需要构建笨重的反向通道。

这可能是一个迭代过程,因为您不需要弄清楚如何解决您尝试编译的特定代码中不存在的歧义。 最终,您可能想要处理所有这些问题,但根据需要进行处理可能会证明是一种更充实的体验。

通常,识别 C++ 中的构造函数(和析构函数)需要特别识别包含 class 的名称,与任何其他标识符不同。

这可以通过在返回不同标记的词法分析器中进行上下文查找来完成。 在构成 class A 主体的{ ... }内,词法分析器可以识别A标记并为其返回不同的标记类型(与将为B返回的 TYPENAME 标记不同)

暂无
暂无

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

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