A deep dive into why some grammars fail, what ambiguity means, and how to fix it before building your parser.
A Context Free Grammar (CFG) is ambiguous if:
This means the grammar does not define a unique structure for some inputs. The compiler won't know which interpretation is the "correct" one.
This string can be interpreted in two ways. Both are perfectly valid according to the grammar rules:
+
/ \
id *
/ \
id id
Evaluates like: (id) + (id * id)
*
/ \
+ id
/ \
id id
Evaluates like: (id + id) * (id)
Result: Same input. Different structure. This is ambiguity.
Compilers must decide:
If ambiguity exists:
Regular expressions:
CFGs:
There is no universal automatic fix. Ambiguity is removed by grammar design rules.
Now * has higher precedence than +. The structure is forced to be deterministic.
Forcing left-associative grouping:
This forces the parser to group operations from left to right (e.g. a + b + c becomes (a + b) + c).
This doesn't remove ambiguity alone, but makes the grammar usable in Top-Down LL parsing (preventing infinite loops).
When multiple productions share a prefix:
This delays the decision until enough tokens have been read, removing conflict during parsing.
Ambiguity is not a parsing bug. It is a grammar design problem.
A good programming language grammar must be:
Ambiguity often leads to:
A grammar is ambiguous if a string has multiple parse trees. To remove it, define precedence, set associativity, remove left recursion, apply left factoring, or redesign the grammar entirely.