【问题标题】:C++ token typesC++ 标记类型
【发布时间】:2023-03-12 04:24:01
【问题描述】:

我假设 C++ 令牌类型(根据 2.7 Tokens [lex.token])不形成相交集(即 int 被认为仅属于 keyword 令牌类型,而不是 keywordidentifier令牌类型)。考虑到这一点,就会出现以下问题。

C++11 引用:

2.2 翻译阶段 [lex.phases]

7 分隔标记的空白字符不再重要。每个预处理令牌都被转换为一个令牌。 (2.7)。生成的标记在句法和语义上进行分析,并作为翻译单元进行翻译。

因此,C++ 文本的句法和语义分析是在文本溢出到标记之后执行的。

另一个 C++11 引用:

2.7 令牌 [lex.token]

令牌:
标识符
关键字
文字
运算符
标点符号

在标准中我找不到operatorpunctuator 语法非终结符的定义。无论如何,根据2.12 Keywords2.13 Operators and punctuators,令牌new 可以是keywordoperator 令牌。 C++ 编译器如何在对代码进行句法和语义分析之前确定new 标记的类型?

【问题讨论】:

  • 当标准显示newdelete 标记出现在多个集合中时,为什么你会假设标记类型不会形成相交集?
  • @Sneftel 如果我们假设相交集,那么根据我对 2.2 的引用,new 将永远不会同时进入 keywordoperator(仅限 keyword),那么有什么意义使集合相交?
  • 运算符和标点符号在 2.13 中定义(尽管它没有指定哪些是运算符,哪些是标点符号)。我认为这个问题的答案只是“它不能”,但我不是编译器专家。
  • @PowerGamer 编译器不需要在那个阶段(或者永远,真的)对令牌进行分类。这些类别只是为了简化标准中的描述。因为new是关键字,也可以是运算符,所以必须在两个组中。
  • @PowerGamer:当然可以将代码拆分成token。它只是无法在没有上下文分析的情况下确定标记的类型,这使得该语言的编译比使用上下文无关语法的语言更复杂。

标签: c++ token language-lawyer


【解决方案1】:

newdelete 是名称由单个标记组成的可重载运算符。

产生式preprocessing-op-or-punc ([lex.operators]/1) 和operator ([over.oper]/1) 删除了标点符号和预处理运算符{ } [ ] # ## ( ) ; : ...、有向图替代标记<: :> 等、不可重载的运算符. .* :: ?、词汇关键字替代标记and and_eq 等,并添加了多令牌运算符 new[]delete[]()[]newdeletenew[]delete[] 包含在 operator 中,因此它们的 operator-function-idoperator new 等)可以遵循其他可重载运算符的规则,而不必重复语言,保持更新,并发明一个新的产生式 (dynamic-function-id?) 出现在任何地方operator-function-id em> 发生。请注意,名称具有标识符的词法形式(sizeoftypeid 等)的不可重载运算符不包含在 operator 中,因此也不包含在 preprocessing-op -or-punc.

虽然这会在 identifierpreprocessing-op-or-punc 产生式之间引入歧义,但这不会以任何方式影响阶段 3 的翻译。对于第 7 阶段,在 keywordoperator 之间存在歧义,这又不是问题,因为 operator 生产和其他包括令牌 newdelete 例如new-expression ([expr.new]) 不引用 keywordoperator 产生式,而是包含直接相关的令牌。

【讨论】:

  • 2.12 Keywords [lex.key], 1) 声明 new 和其他一些是 unconditionally treated as keywords in phase 7。然而,您假设它也可以被视为operator(这在标准 IMO 中已经是一个矛盾),并且还暗示在第 7 阶段不能将new 视为identifier(如果您接受@ 987654346@ 既是keyword 又是operator 令牌,那么您必须同时接受它也是identifier 令牌。
  • 如果 newdelete 被解析为 operator 而不是 identifier 则 [lex.key]/1 不会t 应用(它只能将令牌从生产 identifier 移动到 keyword,而不能从生产 operator 移动)。正如 [gram] 中所讨论的,语法并不旨在准确,因此只要在翻译或解析的后期阶段解决歧义,它就可以包含歧义。
  • 让我们在句法和语义分析之前的第 7 阶段讨论tokentoken 类型是否相交? IE。 new 被视为:1) identifier AND keyword AND operator 同时或作为 2) 一个 (identifier, keyword, operator) 但我们不知道哪个一个。
  • 如何看待模棱两可的解析取决于您;是A * B; 1) expression-statement AND simple-declaration 或 2) ONE OF (expression-statement, simple-declaration )? C++ 编译器必须能够处理语法级别的歧义。
猜你喜欢
  • 1970-01-01
  • 2017-06-03
  • 2012-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-18
相关资源
最近更新 更多