Section 7 · 11 min read
Parsing
FIRST and FOLLOW sets, LL(1) tables, LR(0), SLR, LALR and CLR item sets, conflict rules and the power hierarchy of parsers.
On this page
What a parser decides
The parser takes the token stream and checks it against a context-free grammar. It either builds a parse tree (explicitly or implicitly through semantic actions) or reports a syntax error.
There are two families:
- Top-down parsers build the tree from the root, producing a leftmost derivation. Recursive descent and LL(1) are top-down.
- Bottom-up parsers build the tree from the leaves, producing a rightmost derivation in reverse. LR(0), SLR(1), LALR(1) and CLR(1) are bottom-up, as is operator precedence parsing.
A grammar is ambiguous if some string has two different parse trees (equivalently, two leftmost derivations). No ambiguous grammar is LL(k) or LR(k) for any . Deciding whether an arbitrary CFG is ambiguous is undecidable.
Preparing a grammar for top-down parsing
Left recursion
A rule like sends a top-down parser into an infinite loop. Replace it with
With several alternatives, becomes and . Indirect left recursion (, ) needs substitution first.
Left factoring
If two alternatives share a prefix, , a predictive parser cannot choose. Factor it: , . Removing left recursion and left factoring are necessary but not sufficient for LL(1).
FIRST and FOLLOW
is the set of terminals that can begin a string derived from , plus if .
Rules for :
- If is a terminal, .
- If , add .
- If , add . If can vanish, also add , and so on. If every can vanish, add .
is the set of terminals that can appear immediately to the right of in some sentential form. It never contains .
Rules for FOLLOW:
- Put the end marker in for the start symbol . In these notes the end marker is written .
- For , add to .
- For , or where , add all of to .
Repeat until nothing changes. Rule 3 is where most mistakes happen: you must revisit it after other FOLLOW sets grow.
LL(1) parsing table
For each production :
- For each terminal in , put in .
- If , put in for every , including the end marker.
The grammar is LL(1) exactly when no cell gets two productions. Equivalent test: for every pair of alternatives ,
- ;
- at most one of , derives ;
- if then .
Every left-recursive grammar and every ambiguous grammar fails this test.
Bottom-up parsing and handles
A shift-reduce parser keeps a stack. It shifts input tokens onto the stack and reduces when the top of the stack matches the right side of a production that is a handle. A handle is the right side of the production used in the last step of a rightmost derivation of the current sentential form. Reducing handles in order gives the rightmost derivation in reverse.
The two conflicts:
- Shift-reduce (S/R): the parser cannot decide whether to shift or reduce.
- Reduce-reduce (R/R): two different reductions are possible.
LR(0) items and the canonical collection
An LR(0) item is a production with a dot in its right side, such as . The dot marks how much of the production has been seen. has one item, .
Build the automaton:
- Augment the grammar with . The start state is .
- Closure: if is in the set, add for every production of . Repeat.
- Goto: is the closure of all items for in .
- Keep applying goto on every grammar symbol until no new sets appear.
When GATE asks for "the number of states", it means the number of item sets in this collection, including the start state. The state containing counts as a normal state.
Conflict rules for each LR method
Suppose a state contains a complete item .
| Method | Reduce by on | S/R conflict when | R/R conflict when |
|---|---|---|---|
| LR(0) | every terminal | the state also has any shift item | two complete items in one state |
| SLR(1) | terminals in | a shift terminal is in | two complete items with overlapping FOLLOW sets |
| CLR(1) | the item's own lookahead set | a shift terminal is in that lookahead set | two complete items share a lookahead |
| LALR(1) | lookaheads after merging same-core states | same as CLR, after merging | same as CLR, after merging |
LR(1) items carry a lookahead: . The closure adds for each .
LALR(1) takes the CLR(1) states and merges any states with the same core (same items ignoring lookaheads). Facts used constantly in GATE:
- The number of LALR(1) states equals the number of SLR(1) states, which equals the number of LR(0) states.
- CLR(1) can have more states than LALR(1).
- Merging can never create a new S/R conflict, because the shift actions depend only on the core. It can create a new R/R conflict.
Power hierarchy
For grammars:
All inclusions are strict. Also every LL(1) grammar is LR(1), but an LL(1) grammar need not be LALR(1) or SLR(1). LL(1) and LALR(1) are incomparable. Operator precedence parsers handle only operator grammars (no productions and no two adjacent nonterminals on any right side), and they can even work with some ambiguous grammars by using precedence and associativity.
For languages, LR(1) grammars generate exactly the deterministic context-free languages. LR(0) grammars generate deterministic languages with the prefix property.
Worked examples
Worked example 1: FIRST, FOLLOW and LL(1) table
Grammar (the expression grammar with left recursion removed):
E -> T R
R -> + T R | eps
T -> F Y
Y -> * F Y | eps
F -> ( E ) | id
FIRST sets: , , .
FOLLOW sets:
- from and the start rule.
- since ends the rules for and .
- .
- .
- .
Table (blank cells are errors):
id + * ( ) $
E E->T R E->T R
R R->+ T R R->eps R->eps
T T->F Y T->F Y
Y Y->eps Y->* F Y Y->eps Y->eps
F F->id F->( E )
No cell has two entries, so the grammar is LL(1). There are 13 non-empty cells.
Worked example 2: Counting LR(0) states
Grammar:
S -> ( L ) | x
L -> L , S | S
Augment with .
| State | Items | Reached by |
|---|---|---|
| I0 | , , | start |
| I1 | I0 on S | |
| I2 | , , , , | I0, I2, I7 on ( |
| I3 | I0, I2, I7 on x | |
| I4 | , | I2 on L |
| I5 | I2 on S | |
| I6 | I4 on ) | |
| I7 | , , | I4 on , |
| I8 | I7 on S |
Total: 9 states. No state mixes a complete item with a shift item or with another complete item, so the grammar is LR(0). It is not LL(1) because is left recursive.
Worked example 3: SLR conflict that LALR removes
Grammar:
S -> A a | b A c | d c | b d a
A -> d
After reading b d, the LR(0) state is . contains , which is also a shift symbol. SLR(1) has a shift-reduce conflict on .
With LR(1) lookaheads, the item in this state was created from , so its lookahead is only . Reduce on , shift on : no conflict. The same thing happens in the state after reading d from the start (lookahead for the reduction, shift on ). No two CLR states share a core here, so LALR(1) has the same 11 states as CLR(1) and is conflict free. The grammar is LALR(1) but not SLR(1).
Worked example 4: Merge that creates a reduce-reduce conflict
Grammar:
S -> a A d | b B d | a B e | b A e
A -> c
B -> c
In CLR(1), after a c the state is , and after b c it is . Each state alone is fine, so the grammar is CLR(1) with 14 states.
The two states have the same core. LALR merges them into , which has a reduce-reduce conflict on both and . LALR(1) has 13 states and is not conflict free. The grammar is LR(1) but not LALR(1).
Worked example 5: Counting reductions
Using , , , count the reductions an LR parser makes on id + id * id + id.
- First
id: , , (3). - Second
id: , (2). The parser does not reduce yet because the next token is*. - Third
id: , (2), then (1). - Fourth
id: , (2), then (1).
Total: 11 reductions. The number of reductions equals the number of interior nodes of the parse tree.
Common traps
- Adding to a FOLLOW set. FOLLOW contains terminals and the end marker only.
- Forgetting rule 3 for FOLLOW when the symbol after can derive .
- Thinking left factoring plus left-recursion removal guarantees LL(1). It does not.
- Assuming LL(1) implies LALR(1). It only implies LR(1).
- Saying LALR merging can introduce shift-reduce conflicts. Only reduce-reduce.
- Counting the states of the CLR(1) automaton when the question asks about LALR or SLR. Those two have the LR(0) count.
- Forgetting to count I0 or the accept state when counting LR(0) states.
- Reporting an LR(0) conflict for together with a shift item. Accepting on the end marker is not a conflict in the usual convention.
Quick revision
- Top-down: leftmost derivation. Bottom-up: rightmost derivation in reverse.
- LL(1) cell rule: FIRST of the right side, plus FOLLOW of the left side if the right side can vanish.
- Ambiguous or left-recursive grammars are never LL(1); ambiguous grammars are never LR(k).
- LR(0) reduces on every symbol, SLR on FOLLOW, CLR on item lookaheads, LALR on merged lookaheads.
- States: LR(0) = SLR = LALR CLR.
- for grammars; LL(1) is inside LR(1) only.
- Merging CLR states can only add R/R conflicts.
- Number of reductions in a bottom-up parse = number of interior nodes in the parse tree.