7 lessons
Context-free grammars, the rulebook for valid structure
Why "regular" pattern matching runs out of power for real programming languages, and how context-free grammars describe nested structure precisely.
Ambiguous grammars, and fixing them with precedence and associativity
What it means for a grammar to allow two different valid trees for the same string, why that is a real problem, and the standard rewriting technique that fixes it.
Top-down parsing with recursive descent, in C++
Turning a layered grammar directly into working C++ functions, one non-terminal at a time, and building a real parser that produces an AST.
LL(1) parsing: FIRST, FOLLOW, and parse tables
The formal machinery behind recursive descent — FIRST and FOLLOW sets, how to build an LL(1) parse table, and how to detect when a grammar can't be parsed this way at all.
Bottom-up parsing and LR parsers, building the tree in reverse
How shift-reduce parsing builds a parse tree from the leaves upward using a stack, why it can handle grammars LL(1) cannot, and how the algorithm actually decides what to do.
Constructing an SLR parsing table by hand
The classic numerical: building LR(0) items, the canonical collection, and a full SLR(1) parsing table for a small grammar, then tracing a real parse against it.
Building a complete statement parser in C++
Scaling the expression parser up to a real mini-language with variable declarations, if/else, while loops, and blocks — including a clean fix for the dangling-else problem.