5.2 LR(0) Parsing: Canonical Collection of Items, Closure, GOTO & Table Construction
π‘ Core Intuition: The 3-Second Mental Modelβ
π³ The Everyday Analogy: The Assembly Progress Trackerβ
Imagine building a complex piece of flat-pack furniture with an instruction manual:
- The Production Blueprint:
- The Progress Bookmark (The Dot ):
- : You have opened the box, but haven't assembled anything yet. You are actively searching for the
Legs. - : The legs are fully attached! Your eyes now shift to the next instruction: grab the
Seat. - : The entire chair is completely assembled! You don't need any more parts; you proudly mark this unit finished (Reduce to
Chair).
- : You have opened the box, but haven't assembled anything yet. You are actively searching for the
π» Bridging to Computer Science: Tracking Viable Prefixes via Dot Itemsβ
In bottom-up LR parsing, the compiler does not guess which production to apply ahead of time. Instead, it tracks all partially matched productions simultaneously using LR(0) Items:
- An LR(0) item is simply a grammar production with a marker dot () placed at some position on the right-hand side.
- The symbols to the left of the dot represent what has already been pushed and verified on the parser stack.
- The symbols to the right of the dot represent what the parser expects to see next in the input stream.
- When the dot reaches the extreme right end (), the entire handle has been matched, signaling an immediate Reduce action.
πTable of Contents
- ποΈ Architectural Foundations: The LR(0) State Machine Pipeline
- π Formal Mathematical Foundations: Items, Closure & GOTO
- βοΈ The Canonical Collection Engine: CLOSURE & GOTO
- ποΈ LR(0) Parsing Table Construction Algorithm
- π€Ό Conflicts in LR(0) Grammars
- π Real-World Production Context: How Industry Builds This
- π Numerical Applications & Worked Examples
- π― Exam & Interview Pitfall Check
ποΈ Architectural Foundations: The LR(0) State Machine Pipelineβ
The Canonical LR(0) Collection Pipeline
Generating the DFA of viable prefixes through augmented grammar, closure expansion, and GOTO transitions
Augment Grammar G'
Introduce unique start rule S' β S to define an unambiguous accept state.
CLOSURE Expansion
Inductively add B β β’Ξ³ whenever dot precedes non-terminal B.
GOTO(I, X) Transitions
Advance dot past symbol X and take CLOSURE of resulting items.
Canonical DFA
Complete collection of item sets forming parser ACTION and GOTO tables.
π Formal Mathematical Foundations: Items, Closure & GOTOβ
β The Augmented Grammarβ
Given a context-free grammar , the Augmented Grammar is formed by introducing a fresh start symbol and a single auxiliary production:
Why augment? In the original grammar, the start symbol may appear on the right-hand side of some production rules (e.g. ). Without augmentation, the parser cannot distinguish between completing a nested sub-derivation of and completing the entire compilation. Reducing signals an unambiguous termination condition: the parser halts and safely Accepts the program.
π The LR(0) Itemβ
An LR(0) Item of a grammar is a production with a distinguished dot β’ placed at some position in the right-hand side:
-
For a production with right-hand side of length , there are exactly distinct LR(0) items.
-
Special Case for Epsilon: For an empty production , there is only one LR(0) item:
(Which functions immediately as a completed reduce item!)
The 4 Canonical LR(0) Item Categories
How the position of the dot determines the parser's operational action
Shift Item
Action: Shift- Dot immediately precedes a terminal symbol: A β Ξ± β’ a Ξ².
- Triggers a SHIFT action: pushes terminal 'a' and target state onto the stack.
- Consumes exactly one terminal from the input lookahead stream.
GOTO Item
Action: Non-Terminal Transition- Dot immediately precedes a non-terminal symbol: A β Ξ± β’ B Ξ².
- Triggers CLOSURE expansion: pulls all initial items B β β’Ξ³ into current state.
- Governs parser state transitions after a reduction: GOTO[state, B].
Reduce Item
Action: Reduction- Dot has reached the extreme right of the production: A β Ξ³ β’.
- Entire production handle has been matched and verified on stack.
- Pops |Ξ³| states and symbols from stack; exposes previous state.
Accept Item
Action: Parser Acceptance- Special item derived from the augmented start symbol: S' β S β’.
- Occurs when entire input has been successfully reduced to start symbol S.
- Parser terminates with success: program is grammatically valid.
βοΈ The Canonical Collection Engine: CLOSURE & GOTOβ
The collection of all sets of LR(0) items forms the state space of the DFA of Viable Prefixes.
π The CLOSURE Algorithmβ
If is a set of items for grammar , is constructed inductively:
-
Basis: Every item in is added to .
-
Induction: If and is a non-terminal, then for every production in , add the initial item:
to , if it is not already present.
-
Repeat step 2 until no new items can be added.
π The GOTO Functionβ
Let be a set of items, and let be a grammar symbol. represents the state reached by transitioning across symbol :
Intuitively, advances the dot one position to the right across symbol for all items in where the dot precedes , and then expands the closure of the resulting set.
ποΈ LR(0) Parsing Table Construction Algorithmβ
An LR parsing table contains two distinct components:
- : Indexed by parser state and terminal token (where or
$). - : Indexed by parser state and non-terminal symbol .
Deterministic Population Rulesβ
For each state in the canonical collection:
-
Shift Actions: If where is a terminal, and :
-
Reduce Actions (The Zero-Lookahead Invariant): If (where and is production rule ):
(In an LR(0) parser, reductions are placed blindly across every single terminal column in the row!)
-
Accept Action: If :
-
GOTO Entries: If for non-terminal :
-
Blank Entries: All unpopulated cells in the table represent syntax error states.
π€Ό Conflicts in LR(0) Grammarsβ
Because LR(0) places reductions unconditionally across all terminal columns without checking lookahead, very few practical grammars are strictly LR(0):
- Shift/Reduce (S/R) Conflict: A state contains both a shift item () and a reduce item (). When terminal arrives, the table cannot decide whether to shift or reduce.
- Reduce/Reduce (R/R) Conflict: A state contains two distinct completed reduce items ( and ). The parser cannot decide which reduction to execute.
Definition: A grammar is LR(0) if and only if its LR(0) parsing table contains zero multiply-defined entries (no S/R or R/R conflicts).
π Real-World Production Context: How Industry Builds Thisβ
While pure LR(0) parsers are rarely used directly in production compilers because practical languages have operator precedence that causes LR(0) conflicts:
The LR(0) Canonical Collection of Items is the exact DFA backbone utilized by both SLR(1) and LALR(1) parser generators (such as GNU Bison, Yacc, and Menhir):
- An LALR(1) generator constructs the exact same LR(0) state machine first.
- Only after building the LR(0) state graph does the generator compute lookahead sets to restrict where reductions are placed, transforming row-wide reductions into targeted lookahead slots.
Because the LR(0) state machine merges all derivation contexts with identical cores, the number of states generated is compactβtypically on the order of several hundred to a few thousand states for an entire C or Rust grammar.
π Numerical Applications & Worked Examplesβ
Example 1: Complete Canonical Collection & LR(0) Table Constructionβ
Construct the complete canonical collection of LR(0) items and the parsing table for the grammar:
Step-by-Step Analytical Solution:
Step 1: Number the Productions in Augmented Grammar
- Production (0):
- Production (1):
- Production (2):
- Production (3):
Step 2: Construct the Canonical Collection of States
Initial State :
- Seed item:
- Dot precedes add
- Dot precedes add and
Transitions from :
- :
- Dot precedes add and
- :
- Dot precedes add and
Transitions from :
- (same items as )
- (same items as )
Transitions from :
- (self-loop)
States have dots at the end (completed items).
Total Canonical States = 7 states ( through ).
Step 3: Construct the LR(0) Parsing Table
| State | Action: a | Action: b | Action: $ | GOTO: S | GOTO: A |
|---|---|---|---|---|---|
| 0 | 1 | 2 | |||
| 1 | Accept | ||||
| 2 | 5 | ||||
| 3 | 6 | ||||
| 4 | |||||
| 5 | |||||
| 6 |
Notice that in States 4, 5, and 6, reductions are placed unconditionally across all terminal columns (a, b, and $)!
Because every single cell contains at most one action, the grammar is strictly LR(0)!
Example 2: Proving an Arithmetic Expression Grammar is NOT LR(0)β
Consider the grammar:
Prove analytically that this grammar is NOT LR(0) by constructing the conflicting state.
Step-by-Step Analytical Proof:
-
Augment the grammar: .
-
Compute state :
- Includes
- Includes
- Includes and
- Includes
-
Compute state :
-
Inspect state :
- Item is a completed reduce item. In LR(0), it requires Reduce placed in ALL terminal columns, including
+and$. - Item is a shift item on terminal
+. It requires Shift on column+.
- Item is a completed reduce item. In LR(0), it requires Reduce placed in ALL terminal columns, including
-
Evaluate table cell :
-
A severe Shift/Reduce Conflict exists in state . Therefore, the grammar is NOT LR(0).
π― Exam & Interview Pitfall Checkβ
Question 1: "How many LR(0) items are generated by a production rule of length n, and what is the rule for epsilon productions?"
Key Focus Points:
- A production has symbols on its right-hand side and generates exactly LR(0) items (the dot can occupy positions ).
- For an epsilon production , length . It generates exactly 1 item: . This item is immediately a complete reduce item.
Question 2: "Why does LR(0) table construction place reductions in every terminal column, and why does this cause conflicts?"
Key Focus Points:
- Zero Lookahead: The '0' in LR(0) denotes zero tokens of lookahead. The parser makes reduction decisions based solely on the stack contents without inspecting the next input symbol.
- Resulting Fragility: Whenever a state contains both a shift item and a completed reduce item, placing the reduction across the entire row creates an unavoidable Shift/Reduce conflict under the shift terminal.
Trap 1: Placing reductions only under FOLLOW symbols in an LR(0) table.
Answer: Fatal concept mix-up. Placing reductions only under is the definition of SLR(1), NOT LR(0). In LR(0), reductions MUST be placed in every terminal column plus $.
Trap 2: Believing left-recursive grammars cannot be parsed by LR(0).
Answer: Misconception carried over from LL(1). Bottom-up LR parsers naturally handle left-recursive grammars without infinite loops or stack overflow. In fact, left recursion is preferred in bottom-up parsing because it keeps the stack depth bounded during list processing!