CS With NehalCS With Nehal

SLR Parser Simulator

Enter a context-free grammar and build its LR(0) automaton, FIRST and FOLLOW sets and SLR parsing table, then parse an input string step by step.

Grammar

One rule per line. Use -> or →, ε (or ϵ, or nothing) for an empty right side, and | for alternatives. Spaces between symbols are optional.

Numbered productions (rule 0 is added to augment the grammar)
  1. 0E' → E
  2. 1E → E + T
  3. 2E → T
  4. 3T → T * F
  5. 4T → F
  6. 5F → ( E )
  7. 6F → id
FIRST and FOLLOW sets (click a row to see where they come from)
Non-terminalFIRSTFOLLOW
E'{ (, id }{ $ }
E{ (, id }{ $, +, ) }
T{ (, id }{ $, +, *, ) }
F{ (, id }{ $, +, *, ) }

The grammar is SLR(1): 12 states, no conflicts.

LR(0) Automaton

Each box is a state Iₙ: kernel items above the dashed line, closure items below. • marks how much of a rule has been read. Drag states to rearrange; click a state or a transition to find it in the parsing table.

EETTFF((idid++**EETTFF((ididTTFF((ididFF((idid))++**$$I0E' → • EE → • E + TE → • TT → • T * FT → • FF → • ( E )F → • idI1E' → E •E → E • + TI2E → T •T → T • * FI3T → F •I4F → ( • E )E → • E + TE → • TT → • T * FT → • FF → • ( E )F → • idI5F → id •I6E → E + • TT → • T * FT → • FF → • ( E )F → • idI7T → T * • FF → • ( E )F → • idI8F → ( E • )E → E • + TI9E → E + T •T → T • * FI10T → T * F •I11F → ( E ) •accept

Drag empty space to pan · Ctrl/⌘ + scroll or the buttons to zoom

SLR(1) Parsing Table

ACTION: Sᵢ shift and go to state i, Rᵢ reduce by rule i, Acc accept, blank = error. GOTO: the state to go to after a reduction. Click a cell to see it in the automaton. Drag a column header to reorder columns.

StateACTIONGOTO
+*()id$ETF
0S4S5123
1S6Acc
2R2S7R2R2
3R4R4R4R4
4S4S5823
5R6R6R6R6
6S4S593
7S4S510
8S6S11
9R1S7R1R1
10R3R3R3R3
11R5R5R5R5

Parse an Input String

Terminals: + * ( ) id. Separate tokens with spaces if they could run together. Click a line to see the table cell it used.

LineStackSymbolsInputAction
(1)$0$id * id + id $Shift id, go to state 5 (S5)
(2)$05$ id* id + id $Reduce by F → id (R6), GOTO(0, F) = 3
(3)$03$ F* id + id $Reduce by T → F (R4), GOTO(0, T) = 2
(4)$02$ T* id + id $Shift *, go to state 7 (S7)
(5)$027$ T *id + id $Shift id, go to state 5 (S5)
(6)$0275$ T * id+ id $Reduce by F → id (R6), GOTO(7, F) = 10
(7)$027(10)$ T * F+ id $Reduce by T → T * F (R3), GOTO(0, T) = 2
(8)$02$ T+ id $Reduce by E → T (R2), GOTO(0, E) = 1
(9)$01$ E+ id $Shift +, go to state 6 (S6)
(10)$016$ E +id $Shift id, go to state 5 (S5)
(11)$0165$ E + id$Reduce by F → id (R6), GOTO(6, F) = 3
(12)$0163$ E + F$Reduce by T → F (R4), GOTO(6, T) = 9
(13)$0169$ E + T$Reduce by E → E + T (R1), GOTO(0, E) = 1
(14)$01$ E$Accept

Accepted in 14 steps: the string belongs to the language of the grammar.

Notes

  • Augmenting adds rule 0, S′ → S. Reducing by it can only happen on $, which is how the parser knows the whole input was read: that cell becomes Acc.
  • Shift entries come from transitions on terminals, and GOTO entries from transitions on non-terminals.
  • Reduce entries are what makes the parser SLR: a complete item A → α • in a state puts Rᵢ only under the terminals in FOLLOW(A), not under every terminal as LR(0) would.
  • Stack and Symbols: the stack holds state numbers (two-digit states are written in brackets, so $027(10) is 0, 2, 7, 10). A reduction by a rule with k symbols on the right pops k states, then follows GOTO from the state now on top.
  • Conflicts: a shift/reduce or reduce/reduce conflict means the grammar is not SLR(1). The grammar may still work with a more powerful parser (canonical LR(1) or LALR(1)), or it may be ambiguous and need rewriting.
  • ε-rules: a rule like Q → ε gives the item Q → ε• directly, which is already complete, so the state reduces by it on FOLLOW(Q).

About This Simulation

This SLR parser simulator builds every part of an SLR(1) parser from a grammar you type: the augmented grammar, the LR(0) automaton (canonical collection of LR(0) items), FIRST and FOLLOW sets and the ACTION/GOTO parsing table. It then parses an input string and shows the stack, symbols, remaining input and action on every line.

Features

  • Grammar input with -> or →, ε rules and | alternatives
  • Automatic augmentation with rule 0 (S′ → S) and numbered productions
  • Draggable LR(0) automaton with kernel and closure items
  • FIRST and FOLLOW table with an explanation for each row
  • ACTION and GOTO table with Sᵢ, Rᵢ and Acc entries, synced with the automaton
  • Shift/reduce and reduce/reduce conflict detection
  • Step-by-step parse trace: Stack, Symbols, Input and Action

Topics covered

  • SLR(1) Parsing
  • LR(0) Items
  • Closure and GOTO
  • FIRST and FOLLOW
  • ACTION and GOTO Table
  • Shift-Reduce Parsing
  • Bottom-Up Parsing

Explanation

SLR (Simple LR) parsing is a bottom-up parsing method. The parser reads the input left to right and builds a rightmost derivation in reverse: it shifts tokens onto a stack and reduces them by grammar rules when the top of the stack matches a rule's right side. An SLR parser decides when to reduce using the LR(0) automaton and the FOLLOW sets of the grammar.

How it works

  1. Augment the grammar with a new start rule S′ → S, numbered 0.
  2. Build the LR(0) items. An item such as E → E • + T shows how much of a rule has been seen: the part before the dot has been read.
  3. Start from CLOSURE({S′ → • S}). For each symbol X after a dot, GOTO(I, X) moves the dot over X and takes the closure; each new set of items is a new state.
  4. Compute FIRST for every non-terminal, then FOLLOW, starting with $ in FOLLOW(S′).
  5. Fill the table: a transition on a terminal a gives ACTION[i, a] = Sⱼ; a transition on a non-terminal A gives GOTO[i, A] = j; a complete item A → α • gives Rₖ under every terminal in FOLLOW(A); S′ → S • gives Acc under $.
  6. Parse: look up ACTION[top state, next token]. Shift pushes the next state; reduce by A → α pops |α| states and pushes GOTO[new top, A]; Acc means the input is accepted, and a blank cell is an error.

Why it matters

LR parsers are used by parser generators such as Yacc and Bison, and building an SLR table by hand is one of the most common compiler design exam questions. Practising the item sets, FOLLOW sets and table entries on your own grammars is the fastest way to learn bottom-up parsing.

Frequently Asked Questions

What is the difference between LR(0) and SLR(1)?

Both use the same LR(0) automaton. An LR(0) parser reduces by a complete item on every input symbol, while an SLR(1) parser reduces only on symbols in FOLLOW of the rule's left side. This removes many conflicts, so SLR(1) accepts more grammars than LR(0).

What is a shift/reduce conflict?

A table cell that contains both a shift and a reduce action. The parser cannot decide whether to read the next token or to reduce, so the grammar is not SLR(1). A classic example is S → L = R | R, L → * R | id, R → L on the symbol =.

Why do we augment the grammar?

The new rule S′ → S gives the parser a single, clear point of acceptance: when it can reduce by S′ → S with $ as the next symbol, the whole input has been parsed.

What do Sᵢ, Rᵢ and Acc mean in an SLR parsing table?

Sᵢ means shift the current token and go to state i. Rᵢ means reduce by production number i. Acc means accept the input. A blank cell means a syntax error.

How many states does the LR(0) automaton of the expression grammar have?

The classic grammar E → E + T | T, T → T * F | F, F → (E) | id has 12 states, I₀ to I₁₁, and its SLR table has no conflicts.

Related Simulations