3

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

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

“预处理令牌到 C++ 令牌的转换” 这个 C++ 令牌是什么,为什么一开始没有转换成它?

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

4

2 回答 2

4

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

预处理令牌

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

...

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

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

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

令牌

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

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

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

于 2012-06-17T19:16:50.570 回答
2

一个更简单的解释。

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

这个源代码:

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

变成类似这样的东西:

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

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


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

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

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

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

干杯

于 2012-06-17T23:55:34.837 回答