C ++编译中有哪些不同的令牌类型?

时间:2012-06-17 19:12:08

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

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

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

“将预处理令牌转换为C ++令牌” 什么是这个C ++令牌,为什么它最初没有转换成它?

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

2 个答案:

答案 0 :(得分:4)

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

  

预处理令牌

     
      
  • 头名
  •   
  • 标识符
  •   
  • PP-数
  •   
  • 字符字面
  •   
  • 用户定义字符的字面
  •   
  • 字串文本
  •   
  • 用户定义-字串文本
  •   
  • 预处理-OP-或-PUNC
  •   
  • 每个非白色空格字符,不能是上述
  • 之一   
     

...

     

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

因此,“转换为预处理令牌”是翻译单元和识别单个令牌的过程。

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

  

令牌

     
      
  • 标识符
  •   
  • 关键字
  •   
  • 字面
  •   
  • 运算符
  •   
  • 标点
  •   

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

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

答案 1 :(得分:2)

更简单的解释。

并且,您可能知道,许多编译器都有词法分析过程,源代码分为令牌。

此源代码:

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

转变成类似的东西:

+--------------+------------------+ 
|  TOKEN       |  TEXT            | 
+--------------+------------------+ 
|  void        | "void"           | 
+--------------+------------------+ 
|  identifier  | "main"           | 
+--------------+------------------+ 
|  leftcurly   | "{"              | 
+--------------+------------------+ 
|  identifier  | "int"            | 
+--------------+------------------+ 
|  identifier  | "x"              | 
+--------------+------------------+ 
|  assign      | "="              | 
+--------------+------------------+ 
|  minus       | "-"              | 
+--------------+------------------+ 
|  integer     | "3"              | 
+--------------+------------------+ 
|  minus       | "-"              | 
+--------------+------------------+ 
|  minus       | "-"              | 
+--------------+------------------+ 
|  integer     | "5"              | 
+--------------+------------------+ 
|  semicolon   | ";"              | 
+--------------+------------------+ 
|  identifier  | "printf"         | 
+--------------+------------------+ 
|  leftpar     | "("              | 
+--------------+------------------+ 
|  string      | "Hello World"    | 
+--------------+------------------+ 
|  rightpar    | ")"              | 
+--------------+------------------+ 
|  semicolon   | ";"              | 
+--------------+------------------+ 
|  rightcurly  | "}"              | 
+--------------+------------------+ 
|  comment     | "// void main()" | 
+--------------+------------------+ 

这些称为“令牌”的文本中的每一个都有意义。


有时,在编译过程的其他部分,令牌可能被其他令牌替换:

+--------------+------------------+ 
|  TOKEN       |  TEXT            | 
+--------------+------------------+ 
|  void        | "void"           | 
+--------------+------------------+ 
|  functiondec | "main"           | 
+--------------+------------------+ 
|  leftcurly   | "{"              | 
+--------------+------------------+ 
|  type        | "int"            | 
+--------------+------------------+ 
|  variabledec | "x"              | 
+--------------+------------------+ 
|  assign      | "="              | 
+--------------+------------------+ 
|  negative    | "-"              | 
+--------------+------------------+ 
|  integer     | "3"              | 
+--------------+------------------+ 
|  substract   | "-"              | 
+--------------+------------------+ 
|  negative    | "-"              | 
+--------------+------------------+ 
|  integer     | "5"              | 
+--------------+------------------+ 
|  semicolon   | ";"              | 
+--------------+------------------+ 
| functioncall | "printf"         | 
+--------------+------------------+ 
|  leftpar     | "("              | 
+--------------+------------------+ 
|  string      | "Hello World"    | 
+--------------+------------------+ 
|  rightpar    | ")"              | 
+--------------+------------------+ 
|  semicolon   | ";"              | 
+--------------+------------------+ 
|  rightcurly  | "}"              | 
+--------------+------------------+ 
|  comment     | "// void main()" | 
+--------------+------------------+ 

从“减号”令牌转换为“负号码令牌”,& “减法令牌”是这个“预处理令牌”到“最终令牌”的一个很好的例子。

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

干杯