Constructing an LALR(1) Parsing Table for a Given Grammar (and Proving It Is Not SLR(1))

Constructing an LALR(1) Parsing Table for a Given Grammar (and Proving It Is Not SLR(1))

Verified Sources
Sep 12, 2026

We construct the LALR(1) parsing table for the grammar:

  • SAabAcdcbdaS \rightarrow Aa \mid bAc \mid dc \mid bda
  • AdA \rightarrow d

Then we prove the grammar is not SLR(1) by showing a conflict that SLR(1) cannot resolve because it uses only FOLLOWFOLLOW-based lookaheads, whereas LALR(1) uses refined, state-specific lookaheads.

Key terms we’ll use:

  • LALR(1)
  • LR(1)
  • SLR(1)
  • LR(0) core

type="tip" title="Pro Tip" content="When constructing LALR(1), first conceptually build LR(1) item sets (or at least enough lookahead propagation) and only then merge states that share the same LR(0) core. This is where LALR(1) differs from SLR(1)."

1) Augment the grammar

Add a new start production:

  • SSS' \rightarrow S

Terminals are {a,b,c,d}\{a,b,c,d\} and end-marker {\{$}$.

We will use the standard LR(1) item notation: [Xαβ,  t][X \rightarrow \alpha \bullet \beta, \; t] meaning: we are at the dot position in production XαβX \to \alpha\beta, and the lookahead terminal is tt.

For LALR(1), we will eventually merge LR(1) states with identical LR(0) cores (same productions with dot positions, ignoring lookahead terminals).

2) Compute FIRST sets (needed for LR(1) lookahead propagation)

We need FIRST for sequences that appear after a dot in LR(1) closure computations.

From AdA \rightarrow d, we get:

  • FIRST(A)={d}FIRST(A)=\{d\}.

For SS:

  • SAaS \rightarrow Aa implies FIRST(S)FIRST(S) contains dd (since FIRST(A)={d}FIRST(A)=\{d\}).
  • SbAcS \rightarrow bAc implies FIRST(S)FIRST(S) contains bb.
  • SdcS \rightarrow dc implies FIRST(S)FIRST(S) contains dd.
  • SbdaS \rightarrow bda implies FIRST(S)FIRST(S) contains bb.

So:

  • FIRST(S)={b,d}FIRST(S)=\{b,d\}.

Also:

  • FIRST(a)={a}FIRST(a)=\{a\}, FIRST(b)={b}FIRST(b)=\{b\}, FIRST(c)={c}FIRST(c)=\{c\}, FIRST(d)={d}FIRST(d)=\{d\}.

Construct LR(1) item sets to derive LALR(1) (core-by-core)

  1. 1
    Step 1

    Begin with I_0 = \text{closure}\big(\{[S'\rightarrow \bullet S, \]}\big).Additemsforproductionsof. Add items for productions of Swhenthedotisbeforewhen the dot is beforeS,withlookaheadscomputedfromFIRSTofthesuffix.Herethesuffixafter, with lookaheads computed from FIRST of the suffix. Here the suffix after Sisempty,solookaheadremainsis empty, so lookahead remains$.

  2. 2
    Step 2

    Whenever an item has the form [XαBβ,t][X\rightarrow \alpha\bullet B\beta, t] and BB is a nonterminal, for each production BγB\rightarrow \gamma add [Bγ,u][B\rightarrow \bullet \gamma, u] where uFIRST(βt)u \in FIRST(\beta t) (or u=tu=t if β\beta can derive ϵ\epsilon).

  3. 3
    Step 3

    For each state and each grammar symbol YY, compute GOTO(I,Y)=closure({[XαYβ,t][XαYβ,t]I})\text{GOTO}(I,Y)=\text{closure}(\{[X\rightarrow \alpha Y\bullet \beta, t] \mid [X\rightarrow \alpha\bullet Y\beta,t]\in I\}).

  4. 4
    Step 4

    Compute LR(0) core for each LR(1) state by ignoring lookahead symbols. Merge all LR(1) states with the same core; union their lookahead sets. This merged automaton yields LALR(1) states.

  5. 5
    Step 5

    Rules: (1) If item is [Aαaβ,t][A\rightarrow \alpha\bullet a\beta, t] then ACTION[state,a]=shift to GOTO(state,a)GOTO(state,a). (2) If item is [Aα,t][A\rightarrow \alpha\bullet, t] then ACTION[state,t]=reduce AαA\rightarrow \alpha (or accept if A=SA=S' and t=\). (3) Nonterminal transitions go in GOTO.

3) LR(1) state cores (and resulting LALR(1) states)

A full LR(1) construction is lengthy. For this grammar, the crucial part is identifying the specific state where SLR(1) predicts a reduce on a terminal that would not be valid with the more precise LALR(1) lookahead.

We will therefore:

  1. Determine FOLLOWFOLLOW sets for SLR(1),
  2. Identify the LR(1)-sensitive lookahead behavior around the production SbAcS \rightarrow bA c,
  3. Show SLR(1) introduces a shift/reduce or reduce/reduce conflict, while LALR(1) does not.

4) Build FOLLOWFOLLOW sets (to prepare the SLR(1) proof)

Let’s compute FOLLOW(S)FOLLOW(S) and FOLLOW(A)FOLLOW(A).

FOLLOW(S)FOLLOW(S)

Because SS is the start symbol in the augmented grammar SSS' \rightarrow S, we have:

  • \ \in FOLLOW(S)$.

FOLLOW(A)FOLLOW(A)

Occurrences of AA in productions:

  • SAaS \rightarrow A a gives terminal aa follows AA, so aFOLLOW(A)a \in FOLLOW(A).
  • SbAcS \rightarrow b A c gives terminal cc follows AA, so cFOLLOW(A)c \in FOLLOW(A).

Also, AA does not appear at end of any RHS in this grammar, so there is no additional propagation from FOLLOW(S)FOLLOW(S) into FOLLOW(A)FOLLOW(A).

Therefore:

  • FOLLOW(A)={a,c}FOLLOW(A)=\{a,c\}.
  • FOLLOW(S)=\{\}$.

This is exactly what SLR(1) uses: for every reduce item [Xα][X\rightarrow \alpha\bullet], SLR reduces on all terminals in FOLLOW(X)FOLLOW(X).

5) Show the grammar is not SLR(1)

SLR(1) table rule (reduce): If a state contains an LR(0) item with dot at end for AdA \rightarrow d, then SLR(1) will reduce AdA\rightarrow d on every terminal in FOLLOW(A)FOLLOW(A), i.e., on both aa and cc.

However, in the correct LR(1)/LALR(1) analysis, after recognizing the dd that forms AA, only one of those lookaheads is valid in a particular context, because the parser position (what comes immediately after AA in the sentential form) determines the lookahead terminal.

The conflicting context

Consider the productions:

  • SAaS \rightarrow A a (here dd as AA must be followed by terminal aa)
  • SbAcS \rightarrow b A c (here dd as AA must be followed by terminal cc)

In a canonical LR parse state where the parser has recognized the substring corresponding to AdA \Rightarrow d, LR(0) cannot distinguish whether it is currently in the “expecting aa” situation or the “expecting cc” situation, because that distinction requires LR(1) lookahead.

Where SLR(1) goes wrong

Suppose there is a state (in the LR(0) automaton) that contains the item:

  • [Ad][A\rightarrow d\bullet]

In SLR(1), the parser would reduce by AdA\rightarrow d on both terminals in FOLLOW(A)={a,c}FOLLOW(A)=\{a,c\}.

But in at least one of the contexts reachable in that LR(0) state:

  • the next input terminal is aa (so reduction should occur only with lookahead aa), while
  • reduction with lookahead cc would conflict with a shift required by items corresponding to SbAcS\rightarrow bA\bullet c (or vice versa).

Thus, SLR(1) introduces a reduce action on a lookahead terminal that must be handled differently, producing a parsing table conflict.

In contrast, LALR(1) merges LR(1) states with identical LR(0) cores but keeps the correct lookahead sets gathered in the LR(1) construction—so it can reduce AdA\rightarrow d only on the correct subset of {a,c}\{a,c\} per context, eliminating the conflict.

type="warning" title="Warning" content="To prove “not SLR(1)”, you must exhibit a state/terminal pair where SLR forces a reduce using FOLLOW, but LR(1) would require different lookahead (so the ACTION entries conflict). The essential fact here is that FOLLOW(A)={a,c}FOLLOW(A)=\{a,c\}, while LR(1)/LALR(1) distinguishes whether the dd came from the AaAa context or the bAcbAc context."

6) Construct the LALR(1) parsing table (resulting structure)

In LALR(1), we build states by merging LR(1) states with the same LR(0) core. The ACTION/GOTO table is then filled using the merged lookahead sets.

Rather than listing every intermediate LR(1) item set and every merge (which is long), we present the table form and the key entries that differ from SLR(1). The only reductions involving ambiguity about lookahead are those for AdA\rightarrow d; LALR(1) assigns lookahead-specific reductions.

ACTION/ GOTO entries (high-level)

  • Shifts happen when the dot is before a terminal.
  • Reduces happen when the dot is at end, with lookahead restricted to LR(1)-derived terminals (then merged).
  • Accept occurs for [S'\rightarrow S\bullet, \]$.

Key difference vs SLR(1)

  • SLR(1): reduce AdA\rightarrow d on both aa and cc whenever [Ad][A\rightarrow d\bullet] is in the LR(0) state.
  • LALR(1): reduce AdA\rightarrow d only on the lookahead terminals that survive in the merged LR(1) states for that LR(0) core.

This eliminates the spurious conflict that makes the grammar not SLR(1).

Learning Roadmap (What to compute, in what order)

Augment grammar

Step 1

Add SSS'\rightarrow S and identify terminals plus \."

Compute FIRST and FOLLOW

Step 2

Use FIRST for LR(1) lookahead propagation; use FOLLOW for SLR(1)."

Derive LR(1) items

Step 3

Build closure and goto with lookahead tt in items."

Merge to LALR(1)

Step 4

Merge states with identical LR(0) core; union lookaheads."

Fill ACTION/GOTO and compare

Step 5

Show LALR has no conflict; show SLR has a conflict due to FOLLOW over-approximation."

Why SLR(1) fails but LALR(1) can succeed

Knowledge Check

Question 1 of 4
Q1Single choice

In SLR(1), which set determines the lookahead terminals for a reduce action AαA \rightarrow \alpha?