• ↑↓ pour naviguer
  • pour ouvrir
  • pour sélectionner
  • ⌘ ⌥ ↵ pour ouvrir dans un panneau
  • ←→ pour naviguer
  • esc pour rejeter
⌘ '
raccourcis clavier

What’s Being Compared

Compiler design offers multiple parsing strategies — top-down (LL) and bottom-up (LR) with several variants. Each has different power, table size, and implementation complexity. Understanding the spectrum from LL(1) through LALR helps compiler designers choose the right parsing technique for their language and constraints.

The Core Tension

Parsing power and table size are inversely related across the LR family, and a fundamental trade-off exists between human-readability (LL grammars require grammar transformations) and language coverage (LR handles more constructs natively). The CLR(1) parser is the most powerful but produces impractically large tables — LALR exists precisely to trade a tiny amount of power for dramatically smaller tables.

Comparison

DimensionLL(1)LR(0)LR: SLRLR: CLR (LR(1))LR: LALR
StrategyTop-down, predictiveBottom-up, shift-reduceBottom-up + FOLLOWBottom-up + full lookaheadBottom-up + merged lookahead
Lookahead1 token0 tokensFOLLOW sets1 token (precise)1 token (approximate)
Table sizeSmall (rows = non-terminals)Medium (states = LR(0) items)Medium (SLR states)Very large (thousands of states)Medium (merged states)
Parsing powerLeastLessMediumMostNear-CLR
Grammar requirementNo left recursion, left-factoredLR(0) grammarsSLR grammarsLR(1) grammarsLALR(1) grammars
Error detectionImmediate (empty table cell)At state with no actionAt state with no actionMost preciseNear CLR
ConflictsFIRST/FOLLOW conflictsShift/reduce, reduce/reduceReduced vs LR(0)MinimalPossible reduce/reduce from merging

When to Choose Each

LL(1) / Predictive: When you are hand-writing a parser (recursive descent) or when the grammar is naturally LL(1). Used in many production compilers (GCC, Clang use hand-written recursive descent).

LR(0): Rarely chosen in practice — almost never sufficient for real languages. Useful only as a pedagogical stepping stone to understanding SLR and LALR.

SLR: When the grammar is simple enough that FOLLOW sets provide sufficient conflict resolution. Easier to debug than LALR because the relationship between conflicts and grammar rules is clearer.

CLR / LR(1): When maximum parsing power is needed and table size is not a constraint. Research and educational use mainly — impractical for production compilers due to state explosion.

LALR: The practical sweet spot — the default for parser generators like Yacc and Bison. Handles nearly all programming language constructs with table sizes comparable to SLR.

The Insight

The LR family shows a beautiful engineering trade-off: by adding just enough lookahead information (merge LR(1) states with same core), LALR achieves CLR-like power with SLR-like table sizes. Meanwhile, LL(1) represents an entirely different approach — predicting rather than reducing — which is simpler to implement by hand but requires more grammar transformation. Most modern compilers use either hand-written recursive descent (LL) or generated LALR parsers, with the middle variants (LR(0), SLR, CLR) serving mainly as conceptual building blocks.

Connections