Compiler Design for Programmers: Build Lexers, Parsers, Type Checkers, and Code Generators
Halstead, Corin
Synopsis "Compiler Design for Programmers: Build Lexers, Parsers, Type Checkers, and Code Generators"
What really happens between the source code you write and the program a machine finally executes? Compiler design can appear intimidating—a world of grammars, syntax trees, type systems, intermediate representations, optimizers, instruction selection, and machine-specific details. Compiler Design for Programmers turns that complexity into a practical engineering pipeline you can understand, inspect, and build. Written for programmers, computer science students, software engineers, language-tool developers, and technically curious developers, this book follows Aster, a small statically typed language, from source text to executable behavior. You will learn how to tokenize source code, design deterministic lexers, build recursive-descent and precedence-aware parsers, create useful abstract syntax trees, resolve names through scopes and symbol tables, and implement a practical static type system. From there, the book moves beneath the language surface into intermediate representations, lowering, control-flow graphs, SSA concepts, data-flow analysis, constant folding, dead-code elimination, inlining, optimization safety, instruction selection, register allocation, calling conventions, object files, linking, and runtime integration. You will also discover what separates a teaching compiler from a dependable engineering tool: structured diagnostics, layered testing, fuzzing, differential testing, reproducible builds, incremental compilation, security boundaries, performance measurement, and maintainable pass contracts. A complete end-to-end Aster architecture shows how the pieces fit together before the book expands into modern compiler ecosystems such as LLVM, GCC, MLIR, WebAssembly, JIT and AOT compilation, profile-guided optimization, domain-specific compilers, and language-server tooling. Practical appendices provide a professional compiler-project checklist and show how adding strings, arrays, closures, and modules affects the entire compilation pipeline. Stop treating compilers as black boxes. Learn how executable meaning is built—one representation, invariant, and transformation at a time.