Compiler texts have a reputation for being forbidding, and the reputation is half-earned: the famous references assume you already know why a parser and a symbol table exist, while the beginner-friendly books can leave you unsure how the pieces fit into a production toolchain. The trap is starting with the theory before you have felt the problem it solves.
The order that works is inverted from how the field is usually taught. Build a tiny language end to end first, watch it run, and only then reach for the books that formalize parsing, optimization, and code generation. Each stage then answers a question the previous one raised rather than front-loading abstraction.
Build one first
The best on-ramp is to write a small language and see it execute. Writing An Interpreter In Go walks you through a tree-walking interpreter from lexer to evaluator with no external tools, and its sequel Writing A Compiler In Go adds a bytecode compiler and virtual machine so you understand the tree-walk-to-bytecode jump firsthand. Crafting Interpreters is the standout companion: it builds two complete implementations of the same language, one in Java and one in C, and explains every design decision in prose clear enough to read cover to cover. Finishing any of these gives you a mental model to hang the theory on.
The core references
With a working implementation behind you, the classics stop being intimidating. Engineering a compiler is the modern, readable survey of the whole pipeline and is often the best single textbook for a real course. Compilers, principles, techniques, and tools remains the definitive reference for parsing theory and the formal machinery behind it. For the parsing stage specifically, Parsing techniques catalogs essentially every algorithm in the field, and Language Implementation Patterns is the pragmatic bridge, showing reusable patterns for lexers, parsers, and tree walkers you will actually reuse.
Going deeper
The last arc is optimization and code generation, where compilers earn their keep. Modern compiler implementation in ML structures the entire back half of a compiler around clean intermediate representations and is a rite of passage. Static Single Assignment Book goes deep on SSA, the intermediate form that underpins nearly every modern optimizing compiler, so the analyses in LLVM and GCC stop being mysterious. Throughout, Introduction to Algorithms is the reference to keep nearby, since graph algorithms, dynamic programming, and data structures show up constantly in register allocation and analysis.
Read in this order and compilers shift from a wall of theory into a buildable system you understand from the source text to the emitted code. Follow the full path to go from your first interpreter to an optimizing back end.