你其实一直在用它
前面每一章末尾都有一小节「回流」。这一整章,是一场大回流。你造过的这条流水线 —— 切词、搭树、走一遍树 —— 不是编译器的专利,它藏在你每天用的一大半工具底下。学完这本书,你获得的最实在的东西,是一副能看见「缝」的眼睛:以前是黑箱的地方,现在你能认出它内部的工位。这一章带你把这副眼睛用一遍。
先再看一眼你造的整台机器
临别之前,把整条流水线再完整跑一遍。这台机器,是你这十八章一格一格造出来的 —— 现在你看它,应该每一格都认得:
四个格子,你都亲手造过:扫描器(卷 II)、解析器(卷 III)、求值器(卷 IV),还尝了一口编译器和虚拟机(卷 V)。它对你不再是黑箱了。带着这个,我们去日常工作里认一认它的分身。
那条「三段流水线」,你天天在跨
「切词 → 搭树 → 处理树」这个三段结构,一旦你认识它,会在意想不到的地方反复撞见:
| 你每天用的东西 | 它的「切词」 | 它的「搭树」 | 它对树做什么 |
|---|---|---|---|
| 你的编译器(javac / kotlinc) | 词法分析 | PSI / FIR / AST | 类型检查、生成字节码 |
| 浏览器渲染 HTML | 切成标签记号 | DOM 树 | 布局、绘制 |
| CSS 引擎 | 切选择器 / 属性 | 规则树 / CSSOM | 匹配、计算样式 |
| JSON.parse | 切成 { } [ ] : , 记号 | 对象 / 数组树 | 建成内存对象 |
| 正则引擎 | 切正则元字符 | 正则语法树 | 编译成状态机去匹配 |
| SQL 数据库 | 切 SQL 关键字 | 查询语法树 | 优化成执行计划 |
| Markdown 渲染 | 切标记符号 | 文档树 | 转成 HTML |
| 模板引擎 / GraphQL | 切模板 / 查询记号 | 模板 / 查询树 | 渲染 / 取数 |
每一行,都是你造过的那台机器换了身衣服。它们全都先把一段文本切成有类型的片段,再搭成一棵反映结构的树,再对树做点什么。你现在看这些工具,不再是「用一个黑箱」,而是「用一台我知道内部长什么样的机器」。
逐段回流:每个工位教会你的事
扫描器 → 任何「把文本切成片段」的活
你以后手写一个配置解析、一个 CLI 参数处理、一个日志分析,第一反应会是:先扫描,把它切成有类型的记号,再处理。这个「先分词、再处理」的两段式,会让你的解析代码从一团 indexOf + substring 的意大利面,变成清爽的两层。而且你会本能地想到:带上行号、别在第一个错就崩、把报错说人话(第 6 章)。
解析器 → 任何「嵌套结构」的处理
只要数据是嵌套的(而不是扁平的一行),你就该想到递归下降:一个处理外层的函数,遇到嵌套就递归调用自己(第 8 章)。你也会对「优先级 / 结合性」这类东西祛魅 —— 它们不是玄学,是文法层次的产物(第 9 章)。下次有人问你「这个运算符表达式怎么结合的」,你脑子里浮现的是一棵树,而不是一张要背的表。
求值器 / 编译器 → 任何「遍历一棵树做事」的活
这是回报最大的一段。「递归遍历一棵树,对每种节点做点事」是你职业生涯里出现频率极高的模式:React 渲染组件树、Babel / ESLint / KSP 在 AST 上爬、DOM 操作、文件系统遍历、深拷贝、序列化。你写过的每一个 visitor、每一个递归处理嵌套数据的函数,都是 eval 的近亲(第 11 章)。而「同一趟遍历,可以求值、也可以生成代码」(第 18 章)这个洞察,会让你在设计任何「转换」时都多一个视角。
这本书给你的,不是「会写编译器」这个具体技能(虽然你也确实会了一个小的)。它给你的是一副眼睛:
以前你看一门语言、一个解析库、一个转换工具,看到的是一个「输入进去、结果出来」的黑箱。现在你看到的是内部的工位、工位之间流动的中间产物、以及每一段可能出错的地方。报错时你能判断「这是词法错、语法错、还是运行时错」,从而立刻缩小排查范围。看一个陌生的语言项目源码,你能一眼找到它的 scan / parse / eval 三段骨架。「看穿一个复杂系统」这件事,你在这本书里练了一次最纯粹的 —— 而这个能力,是可以迁移到任何系统上的。
回流
如果你也读过这个书架上的另外两本,这一刻它们连成了一条线:
《求值》用 Racket 当棱镜,让你看穿你每天写的语言 —— 闭包捕获的是盒子、宏活在展开时。它给你的是「原来我天天用的东西是这么回事」的顿悟。
《解释》(这本)让你从零造一门语言 —— 把「看穿」变成「造得出」。你不再只是知道闭包捕获盒子,你亲手写了那个盒子(环境里的键值对)、写了攥着它的那只手(closure 字段)。
看穿(《求值》)和造出(《解释》),是理解一件事的两个深度。合起来,你对「编程语言」这个软件里最像魔法的东西,应该已经没什么敬畏、只剩亲切了。
这一章的一句话
切词、搭树、走一遍树,不是编译器的专利 —— 它藏在你每天的编译器、浏览器、正则、JSON、SQL 底下;这本书真正给你的,是一副能看见这些「缝」的眼睛。
最后一章,我们正式交接:你造完了这一版,该带着什么样的准备,去打开那本一直想读的《Crafting Interpreters》。