Role of Shift-Reduce Parsing (with a Worked Example)

Role of Shift-Reduce Parsing (with a Worked Example)

Verified Sources
Nov 4, 2026

shift-reduce parsing is a bottom-up technique that recognizes strings by repeatedly applying two operations: shift and reduce. The parser maintains a stack and an input pointer; it continues until it reaches an accept state or a reject/error.

In practical parser families, shift-reduce parsing is often implemented as LR parsing (e.g., SLR/LALR/Canonical LR). In that setting, a parsing table chooses an action for the current state and current lookahead token: typically “shift to a new state,” “reduce by production A→βA \rightarrow \beta,” or “accept.” Even when the table is not shown explicitly, the conceptual role is the same: shift builds candidate “handles,” and reduce collapses them into higher-level constructs.

Why shift-reduce matters

  • It performs parsing without recursion and in a single left-to-right pass over the input (with stack-based backtracking-free construction).
  • It directly follows the grammar’s bottom-up structure: start from terminals, then reduce to nonterminals, until the start symbol is formed.

Key terms (role-focused):

  • handle
  • viable prefix
  • lookahead

Important: The parser’s correctness hinges on using the right reduce rules (and when to reduce). In LR parsing, this decision is guided by the automaton state and lookahead, preventing incorrect premature reductions.

Shift-Reduce Parsing (LR) Explanation

Example: Shift-Reduce Parsing for a Small Expression Grammar

We’ll illustrate the mechanics of shift-reduce parsing using a simple grammar for expressions without operator precedence complications:

Grammar GG:

  1. E→E+TE \rightarrow E + T
  2. E→TE \rightarrow T
  3. T→idT \rightarrow id

Goal: parse the token sequence:
$$(id)\ +\ (id)\ Insymbols: In symbols:id + id$.

Assumption about actions (how a trace is possible)

To produce a concrete shift/reduce trace, we must know (or assume) the parser’s decision policy (typically from an LR parsing table). For instructional clarity, we’ll show a valid shift-reduce sequence consistent with bottom-up parsing:

  • reduce each idid to TT,
  • then reduce TT to EE where appropriate,
  • and finally reduce E+TE + T to EE.

This demonstrates the role of shift and reduce, even if we do not display the full LR table.

Notation for the trace

  • Stack shown as a sequence of grammar symbols (left to right).
  • Input shown as unread tokens.
  • Actions:
    • Shift: move next token from input to stack
    • Reduce: replace RHS symbols on top of stack with LHS nonterminal

Shift-Reduce Trace for Parsing $id + id$

  1. 1
    Step 1

    Stack is empty. Input is id+idid + id. The parser will repeatedly choose a shift or reduce based on the current configuration.

  2. 2
    Step 2

    Push the first idid onto the stack. Stack: [idid]. Input: + id+ \, id.

  3. 3
    Step 3

    Match the top-of-stack handle idid to RHS of production T→idT \rightarrow id, replacing it with TT. Stack: [TT]. Input: + id+ \, id.

  4. 4
    Step 4

    Now the stack top TT matches RHS of E→TE \rightarrow T. Replace TT by EE. Stack: [EE]. Input: + id+ \, id.

  5. 5
    Step 5

    Shift the ++ token onto the stack. Stack: [E,+E, +]. Input: [idid].

  6. 6
    Step 6

    Push the next idid. Stack: [E,+,idE, +, id]. Input: (empty).

  7. 7
    Step 7

    Replace idid with TT. Stack: [E,+,TE, +, T]. Input: empty.

  8. 8
    Step 8

    Replace handle E+TE + T on stack with EE. Stack: [EE]. Input: empty.

  9. 9
    Step 9

    Since the input is consumed and the stack contains the start symbol EE, the parser accepts.

What this trace teaches about the role of shift-reduce

  • Shift postpones commitment: the parser collects enough symbols on the stack to potentially form a right-hand side (a handle).
  • Reduce performs commitment: once the handle matches a production, it collapses the recognized structure into a nonterminal. This is how the parser builds larger syntactic constituents from smaller ones.
  • The alternation continues until there is nothing left to read and the stack represents the whole sentence as the start symbol.

Mermaid summary of the role:

type="tip" title="Pro Tip" content="When doing manual shift-reduce traces, always check whether the top of the stack matches the RHS of some production. If it does, you can reduce; otherwise you must shift (assuming your grammar/parser permits that configuration)."

type="warning" title="Warning: Not every grammar supports every naive reduce choice" content="In general, the parser must avoid wrong reductions. LR parsers prevent incorrect reduce choices by using state information and lookahead tokens (via a parsing table), rather than reducing based only on stack contents."

Conceptual Lifecycle of Shift-Reduce Parsing

Shift phase

1

Read the next input token and push it to the stack to extend the current viable prefix."

Reduce phase

2

When the stack top matches a production RHS, replace it with the corresponding LHS nonterminal."

Decision loop

3

Repeat shift/reduce decisions until accept or error."

Accept / error

4

Accept when the start symbol is on the stack and input is fully consumed; otherwise reject."

Action/State viewpoint (how LR connects to shift-reduce)

In an LR parser, the “role” of shift-reduce is realized by a deterministic choice:

  • Shift occurs when the parsing table says to shift for the current (state, lookahead).
  • Reduce occurs when it says to reduce by a specific production for that (state, lookahead).
  • Accept occurs when it indicates the completed parse of the start symbol.

This makes shift-reduce parsing scalable: instead of guessing reductions, the parser uses precomputed automaton logic (parsing table plus states).

Shift vs Reduce in the Worked Example (Counts)

How many shift and reduce operations were applied during the trace of parsing id+idid + id.

Common Questions About Shift-Reduce Role

Knowledge Check

Question 1 of 4
Q1Single choice

In shift-reduce parsing, what does a 'reduce' action do?