Build the DFA of LR(0) items, construct the parsing table, and watch the bottom-up parser accept ccdd step by step. Every shift, reduce, and goto — explained.
ccdd Works — The Big Pictureccdd → CcC → CcC → Cdd → CCC → Scmdcnd. For example: cd, ccd, cdd, ccdd…
Without augmentation, the parser doesn't know when it's done. Consider: after we reduce everything to S, the original grammar has S as the start — but so might other productions. The augmented rule S' → S gives us a unique way to detect acceptance:
S' → S• (dot at the end), it knows the entire input has been successfully parsed. This is the Accept action.
An LR(0) item is a production rule with a • (dot) somewhere in its right-hand side. The dot represents how much of the production we've already matched.
c then C.c. Now we expect C.cC. Reduce! Replace cC with C.Every production generates one item per dot position. Items with the dot at the end are reduce items.
We start with the kernel item S' → •S and apply the closure operation: whenever the dot is before a non-terminal, add all that non-terminal's productions with the dot at the start.
For each symbol after a dot in I₀, we move the dot past that symbol and apply closure to get a new state.
After computing all GOTO transitions, we have 7 states. States where all items are complete are reduce states. The state with S' → S• is the accept state.
Nodes are item sets (states). Edges are labeled with the grammar symbol that triggers the transition. Green edges = terminal (shift), Blue edges = non-terminal (goto).
a, set action[i][a] = sj.A→α•, set action[i][t] = rk for ALL terminals t.A, set goto[i][A] = j.| State | ACTION | GOTO | |||
|---|---|---|---|---|---|
| c | d | $ | S | C | |
ccdd$Watch the LR(0) parser process c c d d $. The parser uses a stack of states and matches the input left-to-right, shifting terminals and reducing when a complete item is found.
| Stack (states) | Remaining Input | Action | Notes |
|---|
C → c to the GrammarConsider what happens if we add C → c (allowing C to derive just c). This creates a state where we've just seen c — but we don't know if we should shift (to match cC) or reduce (treating c alone as C).
c: should we shift (pursue C→cC) or reduce (apply C→c)?| State | c | d | $ |
|---|---|---|---|
| 3 | s3 / r(C→c) | s4 | r(C→c) |
c, the parser doesn't know which action to take.