# 第一章 绪论

## 1. 什么是编译

### 1.1 语言和编译

**机器语言：**&#x8BA1;算机可以直接识别的语言，由0和1组成。例如：`C706 0000 0002`

**缺点：**&#x4E0D;容易理解；不易编写；易错

**汇编语言：**&#x5F15;入了助记符。例如：`MOV X, 2`

**优点：**&#x6BD4;较形象直观

**缺点：**&#x4F9D;赖于特定的机器，不同的机器助记符不同，导致程序员必须记住相应机器的助记符；

编写效率低，一条简单的语句，也需要好几条指令

**高级语言：**&#x7C7B;似于数学定义式或自然语言的简介形式。例如：`x = 2`

**优点：**&#x63A5;近人类的表达习惯；不依赖特定机器；编写效率高

最终，汇编语言和高级语言都要翻译成机器可以识别的机器语言

> 汇编语言 -> 机器语言 （汇编）
>
> 高级语言 -> 汇编语言/机器语言（编译）

**编译：将高级语言（源语言）翻译成汇编语言或机器语言（目标语言）的过程**

### 1.2 编译器的位置

![编译器的位置](https://123904567-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M9-HnMHifkICpaw8S2c%2F-M93Kb12LZ3B-ehaiJMA%2F-M93NpJpZDzLN-EUUIY4%2Fimage.png?alt=media\&token=89325b00-397f-485f-9feb-af5f0401c0b6)

**预处理器：**&#x628A;存储在不同文件中的源程序聚合在一起；把被称为宏的缩写语句转换成原始语句

**可重定位：**&#x5728;内存中存放的起始位置L不是固定的，绝对地址 = 起始位置 + 相对地址

**加载器：**&#x4FEE;改可重定位地址，将修改后的指令和数据放到内存中适当的位置

**链接器：**&#x5C06;多个可重定位的机器代码文件（包括库文件）连接到一起；解决外部内存地址的问题（一个文件可能会引用另一个文件中的数据对象或过程，这些数据对象或过程相对于这个文件来说就是外部内存地址）

## 2. 编译系统的结构

![编译系统的结构](https://123904567-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M9-HnMHifkICpaw8S2c%2F-M9Dupm6rBsPR67N1QLd%2F-M9Dvcz6EFgCE9yF-YVN%2Fimage.png?alt=media\&token=16b23bf0-3ba6-40c0-bb2a-fb409743ac57)

## 3. 词法分析

**主要任务：**&#x4ECE;左向右逐行扫描源程序的字符，识别出各个单词，确定单词的类型。将识别出的单词转换成同一的**机内表达** —— 词法单元（token）形式

**token：**<种别码，属性值>

|   | 单词类型 | 种别                                                                                | 种别码                            |
| - | ---- | --------------------------------------------------------------------------------- | ------------------------------ |
| 1 | 关键字  | program、if、else、then、...                                                          | 一词一码                           |
| 2 | 标识符  | 变量名、数组名、记录名、过程名、...                                                               | 多词一码                           |
| 3 | 常量   | 整型、浮点型、字符型、布尔型、...                                                                | 一型一码                           |
| 4 | 运算符  | <p>算术（+ - * / ++ --）</p><p>关系（> &#x3C; == != >= &#x3C;=）</p><p>逻辑（&#x26; | ~）</p> | <p>一词一码</p><p>或</p><p>一型一码</p> |
| 5 | 界限符  | ; ( ) = { } ...                                                                   | 一词一码                           |

**例子：**

![](https://123904567-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M9-HnMHifkICpaw8S2c%2F-M93Tssc8J43XwEyy4Ak%2F-M93U3hdfXlh4Csn5wi0%2Fimage.png?alt=media\&token=df1b9d02-63db-4b69-ad25-ab351bbf76ef)

## 4. 语法分析

**语法分析器**从词法分析器输出的token序列中**识别出各类短语**，并**构造语法分析树**

**语法分析树**描述了句子的语法结构

![语法分析树](https://123904567-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M9-HnMHifkICpaw8S2c%2F-M93W1wcgNqkhESJvGC5%2F-M93W51Icd6Vpi5S8dXn%2Fimage.png?alt=media\&token=b6f197cd-5590-42fe-ae74-2fa82f04808c)

## 5. 语义分析

**主要任务：**

1. 收集标识符的属性信息
   * 种属（Kind）
     * 简单标量、复合变量（数组、记录、...）、过程、...
   * 类型（Type）
     * 整型、实型、字符型、布尔型、指针型、...
   * 存储位置、长度
   * 值
   * 作用域
   * 参数和返回值信息
     * 参数个数、参数类型、参数传递方式、返回值类型、...
2. 语义检查
   * 变量或过程**未经声明就使用**
   * 变量或过程名**重复声明**
   * **运算分量**类型不匹配
   * **操作符**与**操作数**之间的类型不匹配
     * **数组下标**不是整数
     * 对**非数组变量**使用数组访问操作符
     * 对**非过程名**使用过程调用操作符
     * 过程调用的**参数类型或数目**不匹配
     * 函数**返回类型**有误

## 6. 中间代码生成

### 6.1 常用的中间表示形式

* 三地址码
  * 三地址码由**类似于汇编语言**的指令序列组成，每个指令**最多有三个操作数**
* 语法结构树/语法树

### 6.2 常用的三地址指令

![常用的三地址指令](https://123904567-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M9-HnMHifkICpaw8S2c%2F-M93ezzcRjdeq6mfWJD_%2F-M93f8Ho54XjHAsgjM_t%2Fimage.png?alt=media\&token=f2b88b3d-e1bb-4383-a099-baa9b2d2fa09)

### 6.3 三地址指令的表示

* 四元式
  * （op, y, z, x）
* 三元式
* 间接三元式

### 6.4 三地址指令的四元式表示

![三地址指令的四元式表示](https://123904567-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M9-HnMHifkICpaw8S2c%2F-M93ezzcRjdeq6mfWJD_%2F-M93fKNkTuO2YiCMYArl%2Fimage.png?alt=media\&token=706bc93d-b158-45f4-bef9-d634225efe65)

### 6.5 中间代码生成的例子

![](https://123904567-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M9-HnMHifkICpaw8S2c%2F-M93ezzcRjdeq6mfWJD_%2F-M93fW80EAulBwPk2DeI%2Fimage.png?alt=media\&token=b88089b8-b9bd-4b00-b6e1-35645c0f538b)

## 7. 目标代码生成器

目标代码生成以源程序的**中间表示形式**作为输入，并把它映射到**目标语言**

目标代码生成的一个重要的任务是为程序使用的变量**合理分配寄存器**

## 8. 代码优化

为改进代码所进行的**等价程序变换**，使其**运行得更快**一些、**占用空间更少**一些，或者二者兼顾
