第 9 章 · 06 编译器:经典三段式架构


第 9 章 · 06 编译器:经典三段式架构

本节摘要:编译器线开始。本节讲编译器的经典三段式:前端(词法+语法+语义,产出 AST)、中端(优化)、后端(代码生成)。讲清这个分层,以及为什么分层(前端只管语言、后端只管机器、中端复用)。本节呼应第 4 章——正则引擎是「前端」的微缩,这里深化。

内容来源:基于编译原理整理的导读,呼应本书第 4 章正则引擎。

学习目标

  1. 说清编译器三段式:前端(分析)→ 中端(优化)→ 后端(生成)。
  2. 解释前端的三个阶段:词法、语法、语义。
  3. 理解 AST(抽象语法树)是前后端的桥梁。
  4. 说清为什么分层:语言无关的后端、机器无关的中端,可复用。

一、学习价值:编译器是「语言→可执行」的范本

编译器把源码(人读的语言)翻译成机器码(机器跑的语言)。它的三段式架构是「翻译问题」的经典解法,不只编译器用——SQL 引擎、模板引擎、配置解析都借鉴。理解三段式,你不仅会造编译器,更掌握「语言处理」的通用框架。

呼应第 4 章:正则引擎的「正则字符串→NFA」其实就是「前端」的微缩(词法+构造)。第 9 章把它扩展到完整编程语言。

二、认知拆解:三段式

前端:源码 → AST

前端把源码文本分析成抽象语法树(AST):

  1. 词法分析(lexing):源码字符串 → token 流(标识符/关键字/字面量/符号)。用正则描述 token 模式,正则引擎的用武之地。
  2. 语法分析(parsing):token 流 → AST,按语法规则递归构造。用「递归下降」或「解析器生成器」(yacc/antlr)。
  3. 语义分析:类型检查、作用域解析、变量是否声明等「语义」检查。AST 标注类型信息。

输出:带类型信息的 AST。

中端:优化(可选)

在 AST 或「中间表示」(IR)上做优化:常量折叠(2+3→5)、死代码删除、循环优化、内联。中端独立于语言与机器,可跨编译器复用(LLVM 的核心价值)。

第一个编译器可跳过中端,直接前端→后端。

后端:AST/IR → 目标代码

后端把 AST/IR 翻译成目标机器码(或汇编、或字节码):

  1. 代码生成:遍历 AST,对每种节点生成对应指令。
  2. 寄存器分配:决定哪些变量放寄存器、哪些放内存。
  3. 指令调度:优化指令顺序(利用流水线)。

为什么三段式

分层让每部分独立可复用:

  • 前端只管「语言」(C/Rust/Python 各一种)。
  • 后端只管「机器」(x86/ARM 各一种)。
  • 中端只管「优化」(语言与机器无关)。

N 语言 × M 机器,不分层要写 N×M 个编译器;分层只要 N 个前端 + M 个后端 + 1 个中端。LLVM 的 IR 设计正是这个理念的产物。

三、上手第一步

造编译器从「表达式计算器」起步:2 + 3 * 4 → AST → 求值(24)。这是三段式的微缩:词法(切数字符号)→ 语法(按优先级建 AST)→ 后端(遍历 AST 求值)。参考「Crafting Interpreters」前几章。

本节要点回顾

  1. 三段式:前端(源码→AST)→ 中端(优化)→ 后端(AST→目标码)。
  2. 前端三步:词法(字符串→token)、语法(token→AST)、语义(类型检查)。
  3. AST 是桥梁:前后端通过它解耦。
  4. 分层价值:N 语言 × M 机器,不分层 N×M 编译器,分层 N+M+1。
  5. 呼应第 4 章:正则引擎是前端的微缩。

推荐上手顺序

  1. 写表达式计算器(词法+语法+求值),体会三段式。
  2. 参考「Crafting Interpreters」逐步扩展到变量、控制流、函数。
  3. (进阶)学 LLVM IR,理解现代编译器分层。

下一节讲代码生成 vs 解释执行。

作者与出处
原作者:灏天文库
来源:codecrafters-io
许可证:CC0-1.0
整理人: 灏天文库整理
由灏天文库结构化整理,提供目录导航、全文检索与在线阅读,便于系统化学习
发布者: 作者: 灏天文库 转发
评论区 (0)
U