Principles of Compiler Design · Fall 2026

Principles of Compiler Design

Six compilers in fifteen weeks.

This course does not build one compiler in six pieces. It builds six compilers, each one the previous one with a new language feature threaded through all six phases. By December you will have written the front end six times, and that repetition is the point: the second time you add a construct you will already know which files it touches.

1. Lexicalchars → tokensscanner.l2. Syntaxtokens → ASTparser.y3. SemanticAST → checked ASTsemantic.c4. IRAST → TACtac.c5. OptimizeTAC → better TACtac.c6. CodeGenTAC → MIPScodegen.c

Lecture notes

The theory for each topic, anchored in Compilers: Principles, Techniques and Tools — with diagrams, worked examples and self-check questions. Start here.

Topic 1 — The Structure of a Compiler, and the Theory of Lexical Analysis

Why a compiler is built as a sequence of phases, what each one is responsible for, and the automata theory that makes the first phase a solved problem.

Topic 2 — Grammars, Parsing, Translation — and a Compiler End to End

Context-free grammars and the two families of parser; how attributes turn a parse into a translation; and what happens between a syntax tree and a running program.

Topic 3 — Storage, Scope, and the Run-Time Environment

Where a name lives at run time — in the data area, in a stack frame, or behind a pointer — and the calling conventions that make functions and recursion possible at all.

Topic 4 — Control Flow, Flow Graphs, and What Optimization Actually Is

Lowering structured statements to jumps; basic blocks and the flow graph; and the data-flow framework that makes optimization something you can reason about rather than guess at.

Topic 5 — Decisions, Ambiguity, and Generating Code for Two Machines

The dangling else and how LR parsers resolve it; short-circuit code and backpatching; three ways to compile a switch; and what retargeting a compiler actually costs.

Topic 6 — Measuring, Documenting, and Knowing the Limits of What You Built

No new syntax. What separates a project from a piece of engineering: honest measurement, an accurate account of the limits, and knowing what a production compiler does that yours does not.

Reference

The toolchain →

Tutorials for the four tools this course runs on: make, Git and GitHub, flex, and bison. Start here in week 1.

Grammar reference →

The language as it grows across the six topics, in BNF, with the precedence table and the differences from C.

Schedule

Each topic page collects that topic's class activities, starter code and assignment description.

TopicWeeksDatesIn classProjectDue
Topic 1Compiler Design PhasesWeek 1Sep 8 – Sep 13, 2026activitiesProject 1Sep 13, 2026
Topic 2Compiler for a Starter LanguageWeeks 2–5Sep 14 – Oct 11, 2026activitiesProject 2Oct 11, 2026
Topic 3Compiling Complex Variables and FunctionsWeeks 6–8Oct 12 – Nov 1, 2026activitiesProject 3Nov 1, 2026
Topic 4Compiling LoopsWeeks 9–11Nov 2 – Nov 22, 2026activitiesProject 4Nov 22, 2026
Topic 5Compiling Control Flow — DecisionsWeeks 12–14Nov 23 – Dec 13, 2026activitiesProject 5Dec 13, 2026
Topic 6Compiler Design and ImplementationWeek 15Dec 14 – Dec 20, 2026activitiesProject 6Dec 20, 2026

How the code is organized

Running the compiler

Every folder builds with make and self-tests with make test. You need flex, bison, gcc, and SPIM or QtSPIM to run the generated MIPS.