Check Whether the Given Grammar Is CLR(1)
In compiler courses, “CLR” almost always refers to CLR(1) grammars (a.k.a. LR(1) grammars). A grammar is CLR(1) iff it can be parsed by a deterministic LR parser built from LR(1) items without conflicts. Concretely: construct the LR(1) canonical collection of items, build ACTION/GOTO, and verify there are no shift/reduce or reduce/reduce conflicts.
This section checks the given grammar:
We will determine whether it is CLR(1) by examining the LR(1) parsing behavior around the points where the parser must choose between actions.
Key terms you’ll use:
- LR parsing
- LR(1) item
- ACTION/GOTO table
- Shift/reduce conflict
- Canonical collection of LR(1) items
LR(1) Parsing and Conflicts (overview)
Step 1: Augment the grammar and identify productions
To build LR(1), we augment:
So the productions are:
Terminals: (and end-marker $$$).
We will look for a state where the parser’s choice depends on lookahead in a conflicting way.
Determine if the grammar is CLR(1) by locating any LR(1) ACTION conflicts
- 1Step 1
Start with [S' \rightarrow •S, \]$ and apply closure to generate initial items; closure introduces items for nonterminals immediately after a dot, with lookaheads computed using FIRST sets.
- 2Step 2
From the item [S' \rightarrow •S, \]S' \rightarrow S$.
- 3Step 3
The grammar has both and . The moment the parser has recognized a prefix like (i.e., it has seen then via ), the next input symbol may cause either a reduction of or shifting/continuing for —this is where LR conflict checks matter.
- 4Step 4
In an LR(1) construction, conflicts occur when, for the same state and terminal , ACTION has multiple entries. If no such conflicts arise (and there are no reduce/reduce ambiguities), the grammar is CLR(1).
- 5Step 5
Because this grammar separates the contexts that lead to each alternative using different fixed following symbols ( vs ), the LR(1) lookahead distinguishes reductions; thus no shift/reduce conflict appears, so the grammar is CLR(1).
Step 2: Compute the LR(1) lookahead distinctions for the key ambiguity (after reading )
The potentially confusing part of the grammar is:
Both contain the substring after possibly consuming an extra leading .
Now examine what strings these generate:
- From : since , we get
- From : we get
So:
- The parser should reduce by only when the derivation corresponds to having already completed a in the correct context.
- If the input contains a leading , then the correct derivation must match , not (because cannot produce a leading ).
In LR(1), the lookahead helps the parser decide at the exact reduction time.
Concretely:
- is a complete production when the dot reaches the end: items like tell the parser to reduce with lookahead if is the expected following terminal.
- In , is required immediately after .
- In , is also required immediately after (still ).
Thus, after reading , the next symbol must be for those productions to be valid. That means the parser’s action at the state where items exist will consistently be “reduce ”, and then “reduce ” or “reduce ” depending on how much of the prefix was consumed—without needing to guess between two different continuations on the same lookahead.
Step 3: Check the other alternative containing
The other “almost-overlapping” structure is:
- where gives
- where gives
Again, the symbols immediately following are different:
- In , the symbol after must be .
- In , the symbol after must be (and there is also the leading already).
So LR(1) lookahead will disambiguate reductions involving in the same way.
How to reason about LR(1) conflicts quickly
When a grammar seems ambiguous, look for a single LR(1) state where two different productions could be reduced on the same lookahead terminal. If the grammar forces distinct next terminals (like requiring vs after a common nonterminal), LR(1) lookahead typically prevents conflicts.
Terminology note: CLR(1) vs general LR
Some courses use “CLR” informally for LR-family parsing. In formal CS theory, CLR(1) corresponds to LR(1). If your course instead means CLR(0) or SLR(1), the conclusion can differ.
CLR(1) Decision Roadmap (applied to this grammar)
Add $S' \rightarrow S$
1. AugmentRequired to start LR(1) item construction and define accept with \."
Generate LR(1) item sets
2. Closure/GOTOTrack lookaheads using FIRST sets in closure."
Derive parser actions
3. Build ACTION/GOTOShifts from dots before terminals; reductions from completed items."
Look for ACTION conflicts
4. Conflict checkNo shift/reduce or reduce/reduce in any state ⇒ CLR(1)."
Declare CLR(1) or not
5. ConcludeHere, forced follow-symbols make LR(1) lookahead distinguish choices, so no conflicts arise."
Common edge questions
Knowledge Check
In LR(1)/CLR(1) parsing, conflicts refer to which condition?