TSToolSphere

LR(0) & SLR(1) Parser

engineering100% Client-Side

Build LR(0) item sets and the ACTION/GOTO table for LR(0) or SLR(1), find shift-reduce and reduce-reduce conflicts, and trace a bottom-up parse.

LR(0) & SLR(1) Parser: Parsing Table Generator

Build the canonical LR(0) item sets, the ACTION/GOTO table and a shift-reduce parse, and see any conflicts.

Grammar (one rule per line)

Write rules as A -> α | β with spaces between symbols; use ε (or eps) for the empty string. Symbols that appear on a left-hand side are non-terminals, everything else is a terminal, and the first rule's left-hand side is the start symbol.

Table type

Numbered productions

  1. r0E' → E(augmented)
  2. r1E → E + T
  3. r2E → T
  4. r3T → T * F
  5. r4T → F
  6. r5F → ( E )
  7. r6F → id

SLR(1) check

No conflicts: this grammar is SLR(1).

FOLLOW sets (where SLR(1) places reduces)

Non-terminalFOLLOW
E{ $, +, ) }
T{ $, +, *, ) }
F{ $, +, *, ) }

SLR(1) parsing table

sN = shift and go to state N · rN = reduce by production N · acc = accept

StateACTIONGOTO
+*()id$ETF
0s4s5123
1s6acc
2r2s7r2r2
3r4r4r4r4
4s4s5823
5r6r6r6r6
6s4s593
7s4s510
8s6s11
9r1s7r1r1
10r3r3r3r3
11r5r5r5r5

Parse an input string

Accepted in 14 steps

StepStackInputAction
10id * id + id $Shift id, go to state 5
20 id 5* id + id $Reduce by F → id (r6)
30 F 3* id + id $Reduce by T → F (r4)
40 T 2* id + id $Shift *, go to state 7
50 T 2 * 7id + id $Shift id, go to state 5
60 T 2 * 7 id 5+ id $Reduce by F → id (r6)
70 T 2 * 7 F 10+ id $Reduce by T → T * F (r3)
80 T 2+ id $Reduce by E → T (r2)
90 E 1+ id $Shift +, go to state 6
100 E 1 + 6id $Shift id, go to state 5
110 E 1 + 6 id 5$Reduce by F → id (r6)
120 E 1 + 6 F 3$Reduce by T → F (r4)
130 E 1 + 6 T 9$Reduce by E → E + T (r1)
140 E 1$Accept

Canonical LR(0) item sets (12 states)

I0
  • E' → • E
  • E → • E + T
  • E → • T
  • T → • T * F
  • T → • F
  • F → • ( E )
  • F → • id
on E → I1on T → I2on F → I3on ( → I4on id → I5
I1
  • E' → E •
  • E → E • + T
on + → I6
I2
  • E → T •
  • T → T • * F
on * → I7
I3
  • T → F •
I4
  • F → ( • E )
  • E → • E + T
  • E → • T
  • T → • T * F
  • T → • F
  • F → • ( E )
  • F → • id
on E → I8on T → I2on F → I3on ( → I4on id → I5
I5
  • F → id •
I6
  • E → E + • T
  • T → • T * F
  • T → • F
  • F → • ( E )
  • F → • id
on T → I9on F → I3on ( → I4on id → I5
I7
  • T → T * • F
  • F → • ( E )
  • F → • id
on F → I10on ( → I4on id → I5
I8
  • F → ( E • )
  • E → E • + T
on ) → I11on + → I6
I9
  • E → E + T •
  • T → T • * F
on * → I7
I10
  • T → T * F •
I11
  • F → ( E ) •

About LR(0) & SLR(1) Parser

LR(0) Parsing and Canonical Item Sets

LR parsers read input left-to-right and build a rightmost derivation in reverse — a bottom-up parsing strategy used by many real compiler-generator tools (like yacc/bison), in contrast to the top-down approach LL parsers use. Building an LR(0) parser starts with augmenting the grammar with a new start symbol, then computing the canonical collection of item sets: each item set tracks which productions could be "in progress" at a given parsing state, marked with a dot showing how far into the production the parser has read.

The closure operation expands an item set by adding new items whenever the dot sits before a non-terminal — since that non-terminal's own productions could now also be starting. GOTO transitions connect item sets together based on which symbol is consumed, forming the parsing automaton's state graph, which ultimately becomes the parsing table an actual parser implementation would use to decide shift/reduce actions.

This is genuinely intricate to trace by hand for anything beyond a toy grammar, which is exactly why automating the construction — closure, GOTO, and the resulting state table — matters for verifying compiler-construction coursework.

LR(0) vs SLR(1)

Both tables are built from the same canonical collection of LR(0) item sets; they differ only in where reduce actions go. LR(0) puts a reduce in every column of a state that holds a completed item, while SLR(1) only puts the reduce for A → α under the terminals in FOLLOW(A). That one change resolves many conflicts.

Worked example

The expression grammar E → E + T | T, T → T * F | F, F → ( E ) | id has 12 LR(0) states. As an LR(0) table it has two shift/reduce conflicts on *, in the states holding E → T • and E → E + T •, which also hold T → T • * F. SLR(1) resolves both because * is not in FOLLOW(E) = { +, ), $ }, so the grammar is SLR(1) and id * id + id parses successfully.

The grammar S → L = R | R, L → * R | id, R → L is the textbook case that is not SLR(1): "=" is in FOLLOW(R), so one state gets a shift/reduce conflict on "=". It needs LALR(1) or canonical LR(1) lookaheads.

Frequently Asked Questions

Help Us Improve LR(0) & SLR(1) Parser

Did you find this tool helpful? Tell us how we can make it even better, or report a bug or request a new feature in under 1 minute.

Submit Feedback