【问题标题】:What are the different token types in C++ compilation?C++ 编译中有哪些不同的标记类型?
【发布时间】:2012-06-17 19:12:08
【问题描述】:

Walter Bright 关于 C++ 编译的文章谈到了这两个短语

“转换为预处理令牌。”
什么是初始令牌?预处理令牌是什么样的?

“将预处理标记转换为 C++ 标记” 这个 C++ Token 是什么,为什么一开始没有转换成它?

参考:http://www.drdobbs.com/blogs/cpp/228701711

【问题讨论】:

    标签: c++ parsing compiler-construction compilation lexer


    【解决方案1】:

    预处理标记是预处理器语法的一个元素。来自 C++ 标准中的 [lex.pptoken]:

    预处理令牌

    • 标题名称
    • 标识符
    • pp 号
    • 字面量
    • 用户定义的字符文字
    • 字符串字面量
    • 用户定义的字符串文字
    • 预处理操作或穿孔
    • 不能是上述之一的每个非空白字符

    ...

    预处理标记是翻译阶段 3 到 6 中语言的最小词汇元素。

    因此“转换为预处理标记”是对翻译单元进行词法分析并识别单个标记的过程。

    C++ 标记(实际上只是“标记”)在 [lex.token] 中列出:

    令牌

    • 标识符
    • 关键字
    • 文字
    • 操作员
    • 标点符号

    这些仅在所有其他翻译阶段发生后才存在(宏扩展等)。

    关于整个过程的更多信息,我建议阅读C++标准中的[lex.phases]。

    【讨论】:

      【解决方案2】:

      更简单的解释。

      而且,您可能知道,许多编译器都有词法分析过程,其中源代码被拆分为标记。

      本源代码:

      void main()
      {
        int x = -3 - -5;
        printf("Hello World");
      } // void main()
      

      变成类似这样的东西:

      +--------------+------------------+ |代币 |正文 | +--------------+------------------+ |无效 | “空虚” | +--------------+------------------+ |标识符 | “主要” | +--------------+------------------+ |左卷曲 | "{" | +--------------+------------------+ |标识符 | “整数” | +--------------+------------------+ |标识符 | "x" | +--------------+------------------+ |分配 | “=” | +--------------+------------------+ |减号 | "-" | +--------------+------------------+ |整数 | "3" | +--------------+------------------+ |减号 | "-" | +--------------+------------------+ |减号 | "-" | +--------------+------------------+ |整数 | "5" | +--------------+------------------+ |分号 | “;” | +--------------+------------------+ |标识符 | “打印” | +--------------+------------------+ |左派 | "(" | +--------------+------------------+ |字符串 | “你好世界” | +--------------+------------------+ |正确的 | ")" | +--------------+------------------+ |分号 | “;” | +--------------+------------------+ |右卷曲 | "}" | +--------------+------------------+ |评论 | "// 无效 main()" | +--------------+------------------+

      每一段称为“令牌”的文本都有其含义。


      有时,在编译过程的其他部分,标记可能会被其他标记替换:

      +--------------+------------------+ |代币 |正文 | +--------------+------------------+ |无效 | “空虚” | +--------------+------------------+ |函数dec | “主要” | +--------------+------------------+ |左卷曲 | "{" | +--------------+------------------+ |类型 | “整数” | +--------------+------------------+ |变量dec | "x" | +--------------+------------------+ |分配 | “=” | +--------------+------------------+ |负| "-" | +--------------+------------------+ |整数 | "3" | +--------------+------------------+ |减 | "-" | +--------------+------------------+ |负| "-" | +--------------+------------------+ |整数 | "5" | +--------------+------------------+ |分号 | “;” | +--------------+------------------+ |函数调用 | “打印” | +--------------+------------------+ |左派 | "(" | +--------------+------------------+ |字符串 | “你好世界” | +--------------+------------------+ |正确的 | ")" | +--------------+------------------+ |分号 | “;” | +--------------+------------------+ |右卷曲 | "}" | +--------------+------------------+ |评论 | "// 无效 main()" | +--------------+------------------+

      从“减号”标记到“负号标记”和“减法标记”的转换是“预处理标记”到“最终标记”的一个很好的例子。

      这是一个非常概念性的解释。您可能希望阅读有关您的特定编译器文档的更详细的技术信息。

      干杯

      【讨论】:

      • 谢谢。我本来希望有一些预处理器示例,但这也很棒。
      猜你喜欢
      • 1970-01-01
      • 2017-02-25
      • 2017-10-07
      • 1970-01-01
      • 2010-12-15
      • 1970-01-01
      • 1970-01-01
      • 2013-06-23
      • 2010-09-27
      相关资源
      最近更新 更多