Top-Down and Bottom-Up Parsing Techniques
Parsing converts a sequence of tokens into a structure (usually a parse tree/AST) that follows the rules of a context-free grammar. Two fundamental families of parsing strategies are top-down parsing and bottom-up parsing. A core contrast is that top-down parsers predict productions to match the input, while bottom-up parsers recognize handles and reduce them.
Mermaid intuition: top-down expands; bottom-up reduces.
Key terms you’ll see below include LL parsing and LR parsing.2
Note: This environment currently can’t access the web search tool to fetch and cite sources. The course content below is therefore written as technically accurate general knowledge, but it cannot include the mandatory web-backed citations required by the course format.
Footnotes
LL Parsing and Bottom-Up LR Parsing (overview)
Learning objectives
By the end of this section, you should be able to:
- Explain the operational difference between top-down and bottom-up parsing.
- Describe major top-down techniques: recursive descent and LL(1) predictive parsing.
- Describe major bottom-up techniques: shift-reduce, handles, and LR-family parsers.
- Compare power/constraints: what kinds of grammars each family can handle and why.
1) Top-down parsing: from start symbol to input
A top-down parser starts with the start symbol , then repeatedly chooses a production to expand a nonterminal until the derived sentential form matches the input terminals.
Two common top-down styles
- Recursive descent: implement productions as mutually recursive procedures.
- Predictive parsing (LL(1)): use a single-token lookahead to select which production to use, avoiding backtracking.
In recursive descent, the parser may “guess” by trying alternatives; predictive parsing removes guesswork by using FIRST sets and FOLLOW sets to decide deterministically which production to apply.
Footnotes
-
(Unavailable) Web tool access limit prevented retrieving sources with citations. ↩
Mental model for top-down
Top-down parsing is like rewriting: you keep replacing a nonterminal with a right-hand side until the only remaining symbols are terminals that match the input.
Predictive parsing (LL(1)) table-driven process
- 1Step 1
Push end-marker \ and start symbol onto the stack; set input pointer to the first token.
- 2Step 2
Let be the stack top and be the current lookahead token.
- 3Step 3
If , pop and advance input by one token; otherwise report an error.
- 4Step 4
Use the LL(1) parsing table entry to choose a production .
- 5Step 5
Pop . Push onto the stack in reverse order (so the leftmost symbol of is processed next).
- 6Step 6
If , push nothing (effectively removing from the sentential form).
- 7Step 7
If stack top is \ and lookahead is \ then accept; otherwise, if is empty, report an error.
LL(1): how FIRST/FOLLOW determine the table
For a production :
- For each terminal in [FIRST], add to .
- If , then for each terminal in FOLLOW, add to .
- If the grammar is LL(1) then no conflicts occur (at most one production per table cell).
This is the reason LL(1) parsing is deterministic with one-token lookahead: the computed sets prevent ambiguity in table entries.
Practical constraints of top-down methods
Top-down predictive parsing requires the grammar to be LL(1) (or transformed to be). Many grammars require:
- Left factoring (to handle common prefixes),
- Eliminating left recursion (to avoid infinite expansion in naive predictive methods).
These transformations exist because top-down expansion follows the grammar’s derivational structure, and problematic recursion/prefix ambiguity breaks the “predict with one lookahead” property.
Common failure mode in naive top-down
If a grammar has left recursion and you try recursive descent without transformation, the parser can loop expanding a nonterminal into itself before consuming input.
2) Bottom-up parsing: from input to start symbol
A bottom-up parser works in reverse relative to derivations. Instead of expanding from , it:
- Shifts tokens onto a stack,
- Recognizes a handle (a reducible phrase),
- Reduces the handle to a nonterminal,
- Repeats until it reduces to the start symbol.
Shift-reduce parsers
The general mechanism is called a shift-reduce parser: actions are typically determined by a parsing automaton and lookahead token.
A high-level view:
- Shift: push the next input token to the stack.
- Reduce: replace a stack suffix that matches the RHS of some production with .
- Accept: when the stack contains (plus end-marker) in the right configuration.
Handles and reductions (why bottom-up works)
A bottom-up parse corresponds to finding a sequence of reductions that transforms the input tokens into . Each reduction corresponds to “undoing” a rightmost derivation step (with details depending on parser type). The concept of a handle lets the parser decide which substring to reduce at each step.
Generic shift-reduce parsing loop
- 1Step 1
Put end-marker \ on the stack and set input pointer to the first token.
- 2Step 2
Given stack configuration and current lookahead, decide one of: Shift, Reduce by , or Accept.
- 3Step 3
Push the current lookahead token onto the stack and advance input.
- 4Step 4
Pop symbols from the stack, then push .
- 5Step 5
If action is Accept, the input is successfully parsed.
LR parsing family (the most important bottom-up family)
LR parsing is a bottom-up family parameterized by the amount of lookahead and the strength of the parsing automaton:
- LR(0): simplest but often too weak (many conflicts).
- SLR(1): uses FOLLOW sets to guide reductions, reducing conflicts compared to LR(0).
- LALR(1): merges states of LR(1) items to improve efficiency while maintaining stronger discrimination than SLR(1).
- LR(1): most powerful in the family but can be larger.
These parsers use an automaton of “items” representing possible positions within productions; the parser’s action is determined by:
- a shift or reduce based on lookahead and state,
- the goto transitions for nonterminals after reductions.
Comparing top-down vs bottom-up: power and typical behavior
At a conceptual level:
- Top-down parsers tend to be simpler and can be efficient for suitable grammar classes (e.g., LL(1)).
- Bottom-up parsers are often more powerful and systematic for a broader range of grammars (e.g., LR-family), but are more complex to implement.
A useful comparison table:
| Dimension | Top-down (LL) | Bottom-up (LR) |
|---|---|---|
| Direction | From toward input | From input toward |
| Core idea | Predict productions | Recognize handles and reduce |
| Lookahead | Often (LL(1)) or small | Uses lookahead in automaton (LR(1), etc.) |
| Typical implementation | Recursive descent, predictive parsing tables | Shift-reduce with state/action/goto tables |
Conceptual workflow comparison (qualitative)
A rough visual of how much each approach relies on prediction vs reduction
3) Edge cases and correctness intuition
Why conflicts happen
Both LL and LR table-driven methods can fail if the grammar is not in the right class:
- LL parsing tables can have multiple productions for the same entry.
- LR parsing tables can contain shift/reduce or reduce/reduce conflicts depending on the lookahead/state information.
Ambiguous grammars
If a grammar is ambiguous (can produce multiple parse trees for the same input), no deterministic parser strategy can resolve that ambiguity without extra rules. Parsing techniques reflect grammar class properties, not a general ability to disambiguate arbitrary CFGs.
FAQ and clarifications
How a grammar becomes parsable by each family
Start with a CFG
Step AWrite productions for the language."
Try LL parsing
Step BCompute FIRST/FOLLOW and build LL(1) table; transform grammar if needed (left recursion, factoring)."
Try bottom-up LR parsing
Step CConstruct LR automaton and action/goto tables; select LR variant (SLR/LALR/LR(1)) based on conflicts and size."
Handle conflicts or ambiguity
Step DIf conflicts remain, the grammar may not belong to that deterministic class or may be ambiguous."
Top-down vs Bottom-up Parsing Flashcards
Knowledge Check
Which statement best describes top-down parsing?