解释
你写了很多年代码。你知道 1 + 2 * 3 会先算乘法,知道函数能递归、闭包能记住变量、写错分号会报「语法错误」。这些你都在用。
但是:那个「先算乘法」的规则,是谁、在什么时候、怎么替你决定的?你写下的一行文本,凭什么就能跑起来 —— 中间到底发生了什么?「语法错误」是哪个环节、盯着什么东西时喊出来的?你每天依赖的编译器 / 解释器,掀开盖子,里面是什么?
这本书的答案是:你自己造一个,就全懂了。我们用一门叫 Lox 的小语言(就是《Crafting Interpreters》那门),从头搭一条流水线 —— 扫描器把字符切成记号、解析器把记号搭成语法树、求值器沿着树跑出结果,最后再造一台字节码虚拟机。整台解释器是真写出来的,就在这个网页里跑:你敲一段代码,能亲眼看它一格一格走完这条流水线。
这本书和《Crafting Interpreters》是什么关系
《Crafting Interpreters》(下称 CI)是这个领域公认最好的入门书 —— Bob Nystrom 亲手带你造两个完整的解释器。但它也很厚:两门实现(Java 写的 jlox、C 写的 clox),从头到尾一行不落。很多人(也许包括你)买了、想读、却一直没能开始。
这本《解释》不是要替代它,是要把你送进它。我们只做一件事:用最短的路径,让你亲手造出一个能跑的解释器,尝到那个「我的语言活了」的瞬间。为了让这条路无缝接上 CI,我们用的就是 CI 那门 Lox 语言 —— 语法、语义、连那个经典的闭包例子都一样。等你读完这本、翻开 CI,Lox 的一切你都熟了,jlox 的骨架你已经在脑子里搭过一遍。那本厚书,会突然变得可读。
你写的代码,在被运行之前,只是一段文本 —— 死的。是有一个程序去读它、给它赋予意义,它才动起来。你天天依赖这个程序,却从没见过它。
那个程序没有魔法。它就是一条流水线:切词、搭树、走一遍树。每一段都小到你能亲手写出来。造完一遍,你会永远地改变「看代码」这件事 —— 从此你知道盖子底下是什么。
「整台解释器在浏览器里跑」是什么意思
别的书讲解释器,代码是印在纸上的,你得自己想象它怎么运行。这本书的解释器,是用 JavaScript 真写出来的,就嵌在网页里。所以每一章的 Demo 都不是动画、不是示意图 —— 是真的扫描器、真的递归下降解析器、真的树遍历求值器、真的栈式虚拟机在当场工作:
- 在扫描器那章,你改一个字符,右边的记号流立刻重切;
- 在优先级那章,你输入
1 + 2 * 3,它把括号加满给你看它到底怎么理解的; - 在求值那章,你按「算一步」,看子树一个个塌缩成值;
- 在最后,你能在一个真 REPL 里敲一整个带闭包的 Lox 程序,让它跑出来。
正文里出现的每一个数字(1 + 2 * 3 为什么是 7、fib(10) 为什么是 55、这段代码编成几条字节码),都是这台引擎当场算的,不是我写死的。
这本书假设你已经会什么
写给这样的人
- 能熟练写 Kotlin / Java / JS / TS / Python 中的至少一门
- 用过
if、函数、递归、闭包,但没造过它们 - 一直想读《Crafting Interpreters》,却总没能开始
- 好奇编译器 / 解释器盖子底下是什么,但被「龙书」劝退过
- 想要的是亲手造一遍那种理解,不是背概念
暂时不适合
- 完全没写过代码 —— 这本书假设你有编程基础
- 要的是编译原理的完整理论(自动机、LR、类型系统证明…那是教材的活)
- 想直接上手 LLVM / 做生产级优化编译器(先造一个玩具,再谈这个)
- 受不了「先造个能跑的,再谈严谨」这种顺序
这本书不需要你装任何东西。解释器就在网页里,Demo 就是它本人。你可以只读、只看 Demo,也可以在 REPL 里写自己的 Lox 程序折腾它。
如果你想照着自己写一遍(强烈建议 —— 这才是这本书的正确打开方式),用你最顺手的语言就行:书里的实现思路是语言无关的,本书的引擎用 JS,CI 用 Java / C,你用 Kotlin / Python 都一样成立。
读法
顺着读。这本书是一条流水线:卷 II 造扫描器(词),卷 III 造解析器(树),卷 IV 造求值器(义)—— 到这里你就有一个完整能跑的解释器了。卷 V 再加造一台字节码虚拟机(令),尝一口「真语言为什么要编译」。每一格都接着上一格的产物,跳着读会断链。
每一章的最后都有一节 「回流」:这一课在你每天的 Kotlin / JS 里对应着什么(你的编译器、JS 引擎、正则、JSON 解析、模板引擎…… 干的都是这条流水线上的某一段)。那是你造这个玩具语言,能换回真实世界的东西。