17.2.1 编译程序基本原理
编译器的目标是把源程序翻译成目标程序。但源程序不是一团普通文本,它同时包含单词、句法结构、类型关系、运行含义和目标机器约束。编译器必须分层处理,才能把复杂问题拆成可验证的步骤。
编译器做的事
mermaid
flowchart LR
A["源程序"] --> B["分析"]
B --> C["中间表示"]
C --> D["优化"]
D --> E["目标代码"]分析部分把程序“读懂”,综合部分把读懂后的信息“生成代码”。错误处理和符号表管理贯穿整个过程。
为什么要分阶段
| 阶段划分的理由 | 解释 |
|---|---|
| 降低复杂度 | 先识别单词,再分析句子,再检查含义 |
| 便于定位错误 | 拼写、结构、类型错误分别处理 |
| 便于复用理论工具 | 词法用正规式和自动机,语法用文法和分析树 |
| 便于优化 | 有中间代码后,可做与机器无关或相关的优化 |
必需与可选
词法分析、语法分析、语义分析是理解源程序的核心阶段。中间代码生成和代码优化在许多编译器中很重要,但并不是每个编译器都必须显式设置独立阶段。考试常问“并非所有编译程序都必须经过的阶段”,此时要警惕中间代码生成和优化。
| 内容 | 是否通常必需 | 说明 |
|---|---|---|
| 词法分析 | 是 | 字符流变单词符号 |
| 语法分析 | 是 | 单词符号变语法结构 |
| 语义分析 | 是 | 检查类型、作用域等含义 |
| 中间代码生成 | 不一定 | 为优化和移植提供中间表示 |
| 代码优化 | 不一定 | 改善效率,但不是语义正确的前提 |
| 错误处理 | 贯穿 | 各阶段都可能发现错误 |
| 符号表管理 | 贯穿 | 记录名字、类型、作用域、地址等信息 |
小练习
题:符号表是中间代码的一种形式吗?
答:不是。符号表是编译器管理标识符信息的数据结构,中间代码常见形式包括语法树、后缀表达式、三地址码/四元式等。
自查
- 编译器为什么不能只做一次“文本替换式翻译”?
- 哪些阶段通常负责发现错误?
- 中间代码生成为什么有用但不一定是必需阶段?