Phases of translation
Phases of translation
C源文件由编译器进行处理,就像
下面的阶段发生一样,按照这个顺序。只要行为相同,实际实施可能会将这些行为组合起来或进行不同的处理。
Phase 1
1)源代码文件(通常是一些多字节编码中的文本文件,如UTF-8)的单个字节以实现定义的方式映射到源字符集的字符
。特别是,依赖于操作系统的行尾指示符被换行符替换。的源代码字符集
是一个多字节字符集,其包括基本的源字符集
作为一个单字节子集,其由以下96个字符的:
a)5个空格字符(空格,水平制表符,垂直制表符,换页符,换行符)
b)由10位的字符'0'
,以'9'
C)52页的信件从'a'
到'z'
并且从'A'
至'Z'
d)29个标点符号: _ { } [ ] # ( ) < > % : ; . ? * + - / ^ & | ~ ! = , \ " ’
2)三字母序列被相应的单字符表示替换。
Phase 2
1)每行尾部出现反斜杠(紧接着换行符后面),删除反斜杠和换行符,将两条物理源代码行组合成一条逻辑源代码行。这是一次单程操作:以两条反斜杠结尾并且后跟一条空行的行不会将三行合并为一行。
2)如果一个非空的源文件在这一步之后没有以换行符结尾(不管它最初没有换行符,还是以反斜杠结束),那么行为是不确定的。
Phase 3
- 源文件被分解为注释,空白字符序列(空格,水平制表符,换行符,垂直制表符和换页符)以及
预处理标记
,这些符号
如下
- 标题名称:<stdio.h>或"myfile.h"
- 标识符
- 数字
- 字符常量和字符串文字
- 运营商和标点符号(包括替代令牌),例如+,<<=,<%,##,或and。
- 不符合任何其他类别的单个非空白字符
- 每个评论被一个空格字符替换
- 保留换行符,并且它的实现定义了非新行空白序列是否可以折叠为单个空格字符。
Phase 4
1)执行预处理器。
2)使用#include指令引入的每个文件都会递归执行阶段1到4。
3)在这个阶段结束时,所有预处理器指令都从源代码中删除。
Phase 5
1)字符常量和字符串文本中的所有字符和转义序列都从源字符集
转换为执行字符集
(可能是多字节字符集,例如UTF-8,只要列出基本源字符集中的
所有96个字符在阶段1中具有单字节表示)。如果转义序列指定的字符不是执行字符集
的成员,则结果是实现定义的,但保证不是空(宽)字符。
注意:在这个阶段执行的转换可以通过某些实现中的命令行选项来控制:gcc和clang用于-finput-charset
指定源字符集的编码,-fexec-charset
并-fwide-exec-charset
指定字符串中的执行字符集编码和字符文字没有编码前缀(自C11开始)。
Phase 6
相邻的字符串文字是连接的。
Phase 7
编译发生:令牌在语法和语义上被分析并翻译为翻译单元。
Phase 8
链接发生:满足外部引用所需的翻译单元和库组件被收集到一个程序映像中,该映像包含在其执行环境(OS)中执行所需的信息。