南京大学 NJU 编译原理课程自学指南:用 ANTLR 4 亲手写出一台 C 语言编译器
编译原理不是只有《龙书》里的艰深理论,南京大学的 NJU 编译原理课程给出了一条"先动手、后补理论"的进阶路线:借助当下热门的 ANTLR 4 解析器生成器,从一个个小例子入手,一步步实现属于自己的编译器,最终揭开 C 语言的"神秘面纱"。本文结合《CS 自学指南》仓库中的课程档案,系统梳理这门课的定位、教学理念、ANTLR 4 技术要点、开放资源以及在多门编译课程中的横向对比,帮助自学者快速判断它是否适合自己,并高效投入学习。
课程档案一览
在深入课程内容前,先用课程档案明确它的基本盘(信息取自 docs/编译原理/NJU-Compilers.md):
| 属性 | 说明 |
|---|---|
| 所属大学 | 南京大学 |
| 先修要求 | 离散数学 |
| 编程语言 | Java |
| 课程难度 | 中等偏上(满分五星约三星) |
| 预计学时 | 80 小时 |
| 作业构成 | 10 个书面作业 + 8~10 个编程作业(带你实现一个编译器) |
可以看到,这是一门以 Java 为主语言、以动手实践为灵魂的编译原理课。先修要求仅列出离散数学,对"零编译器基础"的学习者相当友好,80 小时的预算也明显低于许多追求大而全的同类课程。
课程定位:让编译器不再"神秘"
编译原理长期以来被贴上"难学、抽象、理论堆砌"的标签。而南京大学这门课在教学设计上做了两个关键选择,使其成为自学者口中"能真正跟下来"的课程:
- 实践先行,问题驱动。课程最新一版采取了"先用 ANTLR 4 完成一些小例子,再补足理论知识"的顺序。学习者先带着具体问题("这段语法怎么描述?""这颗语法树怎么长出来?")去接触理论,理解深度和记忆效果都远好于先啃定义再做题。
- 工具代劳重复劳动。设计者选用当下热门的 ANTLR(ANother Tool for Language Recognition)v4 作为解析器生成工具。学习者可以专心于词法/语法分析的设计,而让 ANTLR 4 去生成大量重复的模板代码,从而把精力集中在真正有挑战的编译流程设计上。
理论部分基本按照《龙书》(Compilers: Principles, Techniques and Tools)的节奏展开,覆盖了词法分析、语法分析、语义分析、运行时环境、寄存器分配、代码优化与生成等标准主线;而实践部分则成为课程的亮点——由简单到复杂,一步步实现一个属于自己的编译器。在编码、踩坑、调试的循环中,课程档案作者的最大感受是:"心里不再对实现一个编译器有畏难情绪,也不再无从下手",学完后会形成一套初步而行之有效的编译实现思路。
核心工具:ANTLR 4 解析器生成器
ANTLR 4 是贯穿这门课实践环节的关键工具,理解它的定位是跟上课程的前提。
ANTLR 4 是什么
ANTLR 4 是一个 LL 解析器生成器。与 LR、LALR 解析器生成器相比,它能处理的文法类别范围相对狭窄;但反过来,它生成的解析器具有易于理解和易于使用的突出优势,非常适合教学场景——学习者不必在移进/归约的工程细节中消耗过多精力。
关键特性:"无限长 token 超前扫描"
ANTLR 4 支持无限长的 token 超前扫描(lookahead)。这一特性在很大程度上弥补了"可处理语法范围较窄"的短板:传统 LL(1) 解析器只能向前看一个 token,遇到稍复杂的文法便束手无策;而 ANTLR 4 的动态前瞻能力让学习者在课程中书写"直观、贴近语言设计直觉"的文法成为可能,减少为了迁就解析器而扭曲语法描述的情况。
配套 IDE 插件:可视化的语法树
ANTLR 4 在主流 IDE 中均有官方插件。装上插件后,解析过程会产生即时的可视化语法树(parse tree)。对于刚接触词法/语法分析的自学者,亲眼看到一段 C 语言代码如何被拆分、组织成一棵语法树,比任何文字讲解都更直观,这也是该课程降低前端理解门槛的重要设计。
面向社会自学的开放性
南京大学这门课在资源开放程度上对自学者极其慷慨,课程档案总结了以下四点:
- Online Judge 向校外学生开放:非南大学生同样能使用课程的 Online Judge 提交作业并得到评测反馈,这是把"自学"落地的关键——没有 OJ 的课程实践很容易变成"照着示例抄一遍"。
- 参与课程讨论:校外学习者也可以参与课程讨论,与校内学生同步交流。
- 历年资料整理完善:老师极为细心地整理了历年学习资料,在课程网站上很容易找到,过往作业、讲义与常见问题都可自助查阅。
- Zulip 教学群开放:老师把教学班的 Zulip 地址公开(若有变更,在课程网站也能找到),你可以在上面提问,也能看到正在学习相同内容的南大学生的提问,这些问题都会得到助教和老师的回答。对自学者而言,这意味着踩坑经验与答疑资源是共享的,无需自己闭门造车。
课程资源清单
| 资源类型 | 内容 |
|---|---|
| 课程网站 | http://docs.compilers.cpl.icu/(含课件、OJ、历年资料、Zulip 入口) |
| 课程视频 | https://space.bilibili.com/479141149/lists/2312309 |
| 课程教材 | 《龙书》等(Compilers: Principles, Techniques and Tools) |
| 课程作业 | 10 个书面作业 + 8~10 个编程作业,带你实现一个编译器 |
在《CS 自学指南》中的横向坐标
在 CS 自学指南 中,这门课收录于 docs/编译原理 目录,与北京大学、斯坦福、上海交通大学、中国科学技术大学、KAIST 的编译课程并列。仓库中的 CS 学习规划 在"编译原理"一节给出总体建议:"没有什么能比自己写个编译器更能加深对编译器的理解了",并提示该目录下有众多优质课程可选。
用仓库中这几份课程档案的真实信息做横向对比,可以更清楚地看到 NJU 这门课的位置:
| 课程 | 所属学校 | 编程语言 | 实践形态 | 预计学时 | 难度 |
|---|---|---|---|---|---|
| NJU 编译原理 | 南京大学 | Java + ANTLR 4 | 用 ANTLR 4 辅助实现一个自己的编译器 | 80 小时 | 三星 |
| PKU 编译原理实践 | 北京大学 | C/C++/Rust 任选 | 从空目录构建类 C 语言(SysY)→ RISC-V 汇编编译器 | 60 小时 | 四星 |
| Stanford CS143 | 斯坦福 | Java 或 C++ | 为 COOL 语言实现编译器,输出 MIPS 汇编 | 150 小时 | 五星 |
| SJTU 编译原理 | 上海交通大学 | C++ | 实现 Tiger 语言编译器,覆盖 LLVM IR 与寄存器分配 | 150 小时 | 四星 |
| USTC 编译原理 | 中国科学技术大学 | C++ | Cminusf → LightIR(LLVM 子集)→ 龙芯汇编 | 100 小时 | 四星 |
| KAIST CS420 | KAIST | Rust | 面向真实 C 语言,聚焦 IR 设计与 RISC-V 代码生成 | 80 小时 | 四星 |
从中可以读出 NJU 编译原理的差异化定位:
- 上手门槛适中:先修仅需离散数学,编程语言是生态成熟、IDE 插件完善的 Java,又由 ANTLR 4 代劳词法/语法分析的模板代码,比 CS143 的 150 小时、SJTU 的空文件起步或 PKU 的全手写 Koopa IR 路线都要温和;
- 强调"从工具出发理解原理":ANTLR 4 的 LL 解析体系与可视化语法树,让解析器前端不再是黑盒;
- 与 C 语言深度绑定:课程通过理论学习逐渐揭开 C 语言的"神秘面纱",实践主线最终指向一个能用于理解真实 C 语言的编译器,而不是停留在玩具语言层面。
因此,如果你已经具备 Java 与离散数学基础、想用相对可控的 80 小时建立完整的编译器实现框架、又不希望被繁琐的 Lex/Yacc 工程细节劝退,NJU 编译原理是编译原理目录里非常合适的"第一门编译器课";若想要更大的自由度与挑战,可以在学完后衔接 PKU(全手写 IR 到真实 RISC-V)或 SJTU(Tiger 语言 + LLVM 后端)。
自学实操建议
结合课程档案中的信息,给准备投入这门课的自学者几条可执行的建议:
- 先装好 ANTLR 4 与 IDE 插件再开工:让插件在编辑文法时实时展示语法树,你会更快理解"文法 → 解析器 → 语法树"这条链路。
- 严格按照"小例子先行"的节奏走:不要跳步直接上大作业。课程设计本身就预设了"先完成小例子再补理论"的路径,跟随它的顺序能最大化"问题驱动"的效果。
- 善用 Zulip 与历年资料:先在课程网站的历年资料与 Zulip 历史讨论中检索,再提问;你的问题大概率有人踩过。
- 10 个书面作业 + 8~10 个编程作业全部跟完:书面作业巩固龙书理论,编程作业则把一个完整编译器拆成递进的里程碑,两者配合才能做到既懂原理、又真能写出来。
- 以"揭开 C 语言的秘密"为验收标准:学完后试着用你自己的编译器去编译并运行真实的 C 语言程序,验证自己对词法、语法、语义与运行时各阶段的理解是否真正打通。
小结
南京大学 NJU 编译原理课程在众多编译课程中走出了一条务实路线:以 ANTLR 4 这把"顺手的工具"降低前端门槛,以"先实践后理论"的教学编排降低认知负担,以开放的 OJ、Zulip 与历年资料解决自学者最痛的问题——没有同伴、没有反馈、没有路径。它不能替代你在《龙书》上的阅读投入,但能让你在 80 小时内,亲手写下一个真正属于自己的编译器。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00