G27
Self-checkedTier 1 12 min readcd.grammar-ambiguity-transformations

Ambiguity, left recursion and left factoring

Preparing a grammar for parsing: recognising ambiguous grammars, removing ambiguity by precedence and associativity layers and the matched-unmatched rule for dangling else, eliminating immediate and indirect left recursion, and left factoring, with the effect of each on the parse tree.

Why it exists

A parser must be able to decide, for every sentence, which tree it has, and top-down parsers must also be able to decide, from one token, which production to use. Real grammars as people first write them often fail both tests: the natural grammar for expressions is ambiguous, the natural way of writing a list is left-recursive, and two alternatives often begin with the same symbols. This page shows how to rewrite such grammars without changing the language so that parsers can use them.

Prerequisites

You need context-free grammars, derivations and parse trees (context-free grammars). Quick recap: a derivation replaces a nonterminal by the right side of one of its productions at each step; in a leftmost derivation the leftmost nonterminal is replaced each time, in a rightmost one the rightmost. Each parse tree corresponds to exactly one leftmost and exactly one rightmost derivation.

Precise definitions

Ambiguous grammar. A grammar is ambiguous if some string of its language has more than one parse tree. Equivalently: more than one leftmost derivation, or more than one rightmost derivation. (Two different derivations with the same tree, such as a leftmost and a rightmost one, do not make a grammar ambiguous.)

Ambiguity is a property of the grammar, not of the language: many languages have both ambiguous and unambiguous grammars. A language is inherently ambiguous if every grammar for it is ambiguous; for example {aibjck:i=j or j=k}\{a^i b^j c^k : i = j \text{ or } j = k\}. It is undecidable whether an arbitrary context-free grammar is ambiguous, so there is no algorithm that settles it for all grammars; for a given small grammar you look for a string with two trees.

Why it matters: the meaning of a program is attached to its parse tree, so two trees mean two meanings. Every LL(1) and every LR(k) grammar is unambiguous, so an ambiguous grammar is never LL(1) or LR(k); parser generators such as Yacc nevertheless accept some ambiguous grammars and resolve the conflicts with precedence and associativity declarations.

Removing ambiguity from expressions. The grammar E→E+E∣E∗E∣(E)∣idE \to E + E \mid E * E \mid (E) \mid \text{id} gives no precedence and no associativity. Fix it by layering, one nonterminal per precedence level, lowest precedence at the top:

E→E+T∣T,T→T∗F∣F,F→(E)∣id.E \to E + T \mid T, \qquad T \to T * F \mid F, \qquad F \to (E) \mid \text{id}.

A production of the form E→E+TE \to E + T is left recursive, which makes ++ left associative: a+b+ca + b + c is (a+b)+c(a + b) + c. A right-associative operator (such as exponentiation or assignment) uses right recursion: P→F∧P∣FP \to F \wedge P \mid F. Binding tighter means being deeper in the layering: ∗* is generated below ++, so a+b∗ca + b * c must group as a+(b∗c)a + (b * c).

Dangling else. In S→if E then S∣if E then S else S∣otherS \to \text{if } E \text{ then } S \mid \text{if } E \text{ then } S \text{ else } S \mid \text{other} the string if E then if E then S else S has two trees (the else belongs to the inner or the outer if). The rule of nearly all languages is: each else matches the nearest unmatched then. The unambiguous grammar separates the two kinds of statement:

S→M∣UM→if E then M else M∣otherU→if E then S∣if E then M else U\begin{aligned} S &\to M \mid U\\ M &\to \text{if } E \text{ then } M \text{ else } M \mid \text{other}\\ U &\to \text{if } E \text{ then } S \mid \text{if } E \text{ then } M \text{ else } U \end{aligned}

(M is a matched statement, U an unmatched one.) The then branch before an else must be matched, so no else can slip past an inner unmatched if.

Left recursion. A grammar is left recursive if some nonterminal AA derives AαA\alpha for some α\alpha (A⇒+AαA \Rightarrow^+ A\alpha). It is immediate if there is a production A→AαA \to A\alpha and indirect if the cycle goes through other nonterminals. A top-down parser (recursive descent or LL(1)) loops forever on it: to expand AA it expands AA again without consuming a token. Bottom-up (LR) parsers have no problem with it; in fact left recursion makes them use less stack.

Immediate. If A→Aα1∣⋯∣Aαm∣β1∣⋯∣βnA \to A\alpha_1 \mid \dots \mid A\alpha_m \mid \beta_1 \mid \dots \mid \beta_n where no βi\beta_i begins with AA, replace by

A→β1A′∣⋯∣βnA′,A′→α1A′∣⋯∣αmA′∣ε.A \to \beta_1 A' \mid \dots \mid \beta_n A', \qquad A' \to \alpha_1 A' \mid \dots \mid \alpha_m A' \mid \varepsilon.

The new grammar generates the same strings (a β\beta followed by any number of α\alpha's) but is right recursive.

Indirect (the general algorithm). Number the nonterminals A1,…,AnA_1, \dots, A_n. For i=1i = 1 to nn: for j=1j = 1 to i−1i-1, replace every production Ai→AjγA_i \to A_j\gamma by Ai→δ1γ∣⋯∣δkγA_i \to \delta_1\gamma \mid \dots \mid \delta_k\gamma where Aj→δ1∣⋯∣δkA_j \to \delta_1 \mid \dots \mid \delta_k are the current productions of AjA_j; then eliminate the immediate left recursion of AiA_i. (The algorithm assumes the grammar has no cycles A⇒+AA \Rightarrow^+ A and no ε\varepsilon-productions.)

Left factoring. If two alternatives of AA begin with the same string, A→αβ1∣αβ2A \to \alpha\beta_1 \mid \alpha\beta_2, a predictive parser cannot choose between them by looking at the next token. Defer the decision:

A→αA′,A′→β1∣β2.A \to \alpha A', \qquad A' \to \beta_1 \mid \beta_2.

Repeat until no two alternatives share a prefix.

Effects on the tree. Removing left recursion or factoring changes the shape of the parse tree and the grammar but not the language. In particular after removing left recursion from E→E+T∣TE \to E + T \mid T the tree of a+b+ca + b + c leans to the right even though ++ is still meant to be left associative; the semantic actions (see translation schemes) must compensate. Left factoring does not remove ambiguity: the dangling else stays ambiguous after factoring.

How it works

First the ambiguity. The grammar E→E+E∣E∗E∣(E)∣idE \to E + E \mid E * E \mid (E) \mid \text{id} is run on the string id+id∗id\text{id} + \text{id} * \text{id} and the leftmost derivations found by exhaustive search are shown as trees growing. There are exactly two. In the first the root production is E→E+EE \to E + E (so the product is computed first, which is the usual meaning); in the second the root is E→E∗EE \to E * E (the sum is computed first).

Derivation of id + id * id with + at the root: start

Parser run by a script, not typed

Leftmost derivation (the sentential form is on the left; the string to derive is on the right).

  1. 1E → E + E
  2. 2E → E * E
  3. 3E → ( E )
  4. 4E → id
sentential form
E
string to derive
id+id*id
action start
parse tree so far
E

Step 0

Start from E. A leftmost derivation always replaces the leftmost nonterminal; each step corresponds to one node of the parse tree being expanded.

0 / 5
computed by script: the algorithm is executed, one move per step. python3 scripts/gen-cd-traces.py

Derivation of id + id * id with * at the root: start

Parser run by a script, not typed

Leftmost derivation (the sentential form is on the left; the string to derive is on the right).

  1. 1E → E + E
  2. 2E → E * E
  3. 3E → ( E )
  4. 4E → id
sentential form
E
string to derive
id+id*id
action start
parse tree so far
E

Step 0

Start from E. A leftmost derivation always replaces the leftmost nonterminal; each step corresponds to one node of the parse tree being expanded.

0 / 5
computed by script: the algorithm is executed, one move per step. python3 scripts/gen-cd-traces.py

The layered grammar E→E+T∣TE \to E + T \mid T, T→T∗F∣FT \to T * F \mid F, F→(E)∣idF \to (E) \mid \text{id} derives the same string in exactly one way (found by the same exhaustive search):

The only derivation of id + id * id in the layered grammar: start

Parser run by a script, not typed

Leftmost derivation (the sentential form is on the left; the string to derive is on the right).

  1. 1E → E + T
  2. 2E → T
  3. 3T → T * F
  4. 4T → F
  5. 5F → ( E )
  6. 6F → id
sentential form
E
string to derive
id+id*id
action start
parse tree so far
E

Step 0

Start from E. A leftmost derivation always replaces the leftmost nonterminal; each step corresponds to one node of the parse tree being expanded.

0 / 8
computed by script: the algorithm is executed, one move per step. python3 scripts/gen-cd-traces.py

The number of parse trees of the flat grammar for nn binary operators in a row is the Catalan number Cn=1n+1(2nn)C_n = \frac{1}{n+1}\binom{2n}{n}: 1, 2, 5, 14 for n=1,2,3,4n = 1,2,3,4 (counted by two independent methods in the checks). So id+id+id+id has 5 trees.

Worked examples

EX 1Show a grammar is ambiguous

Easy

Show E→E+E∣E∗E∣idE \to E + E \mid E * E \mid \text{id} is ambiguous. Take id+id∗id\text{id} + \text{id} * \text{id}. Tree 1 has ++ at the root with the right operand id∗id\text{id} * \text{id}: derivation E⇒E+E⇒id+E⇒id+E∗E⇒…E \Rightarrow E + E \Rightarrow \text{id} + E \Rightarrow \text{id} + E * E \Rightarrow \dots. Tree 2 has ∗* at the root with the left operand id+id\text{id} + \text{id}: E⇒E∗E⇒E+E∗E⇒…E \Rightarrow E * E \Rightarrow E + E * E \Rightarrow \dots. Two trees for one string, so the grammar is ambiguous (the animations above show both).

EX 2Layering for precedence and associativity

Easy

Make ∗* bind tighter than ++, both left associative, and let ∧\wedge (exponent) bind tightest and associate to the right. Layers from lowest to highest binding: E→E+T∣TE \to E + T \mid T, T→T∗P∣PT \to T * P \mid P, P→F∧P∣FP \to F \wedge P \mid F, F→(E)∣idF \to (E) \mid \text{id}. Check: a∧b∧ca \wedge b \wedge c groups as a∧(b∧c)a \wedge (b \wedge c) because the recursion in PP is on the right; a∗b∗ca * b * c groups as (a∗b)∗c(a * b) * c because the recursion in TT is on the left; and a+b∗c∧da + b * c \wedge d groups as a+(b∗(c∧d))a + (b * (c \wedge d)).

EX 3Immediate left recursion

Medium

Remove the left recursion from E→E+T∣TE \to E + T \mid T, T→T∗F∣FT \to T * F \mid F, F→(E)∣idF \to (E) \mid \text{id}. For EE: α=+T\alpha = + T and β=T\beta = T, so E→TE′E \to T E' and E′→+TE′∣εE' \to + T E' \mid \varepsilon. For TT: T→FT′T \to F T' and T′→∗FT′∣εT' \to * F T' \mid \varepsilon. FF is unchanged. The result (checked by the script to be exactly this) is

E→TE′,E′→+TE′∣ε,T→FT′,T′→∗FT′∣ε,F→(E)∣id.E \to T E',\quad E' \to + T E' \mid \varepsilon,\quad T \to F T',\quad T' \to * F T' \mid \varepsilon,\quad F \to (E) \mid \text{id}.

This is the grammar used for LL(1) parsing. A second case: A→Aa∣Ab∣c∣dA \to A a \mid A b \mid c \mid d becomes A→cA′∣dA′A \to c A' \mid d A' and A′→aA′∣bA′∣εA' \to a A' \mid b A' \mid \varepsilon.

EX 4Left factoring the if statement

Medium

S→i E t S∣i E t S e S∣aS \to \text{i}\,E\,\text{t}\,S \mid \text{i}\,E\,\text{t}\,S\,\text{e}\,S \mid \text{a}, E→bE \to \text{b}. The first two alternatives share the prefix i E t S\text{i}\,E\,\text{t}\,S. Factor: S→i E t S S′∣aS \to \text{i}\,E\,\text{t}\,S\,S' \mid \text{a} and S′→e S∣εS' \to \text{e}\,S \mid \varepsilon. Now the choice at the start of SS is made on one token (i\text{i} or a\text{a}). But the grammar is still ambiguous: on the input i b t i b t a e a the e can be taken by either S', so factoring did not fix the dangling else. (The original grammar has two trees for this input; the checks confirm it.)

EX 5Indirect left recursion

GATE level

S→Aa∣bS \to A a \mid b, A→Ac∣Sd∣eA \to A c \mid S d \mid e. Here S⇒Aa⇒SdaS \Rightarrow A a \Rightarrow S d a, so SS is left recursive through AA. Order the nonterminals S,AS, A. For SS: no earlier nonterminal, and no immediate left recursion. For AA: substitute SS in A→SdA \to S d: A→Ac∣Aad∣bd∣eA \to A c \mid A a d \mid b d \mid e. Now remove the immediate left recursion of AA: α∈{c, ad}\alpha \in \{c,\ a d\}, β∈{bd, e}\beta \in \{b d,\ e\}, giving

A→bdA′∣eA′,A′→cA′∣adA′∣ε.A \to b d A' \mid e A', \qquad A' \to c A' \mid a d A' \mid \varepsilon.

The final grammar is S→Aa∣bS \to A a \mid b plus these (compared with the script's output and with the original language up to strings of length 7).

Cheat box

Cheat box

  • Ambiguous = some string has two parse trees (two leftmost derivations). Deciding it for any CFG is undecidable.
  • Precedence: higher precedence = deeper layer. Associativity: left recursion for left-associative, right recursion for right-associative.
  • Dangling else: match each else with the nearest unmatched then (matched and unmatched statements).
  • A→Aα∣βA \to A\alpha \mid \beta becomes A→βA′A \to \beta A', A′→αA′∣εA' \to \alpha A' \mid \varepsilon.
  • A→αβ1∣αβ2A \to \alpha\beta_1 \mid \alpha\beta_2 becomes A→αA′A \to \alpha A', A′→β1∣β2A' \to \beta_1 \mid \beta_2.
  • Left recursion hurts top-down parsers only. Left factoring does not remove ambiguity.
  • nn binary operators of one flat grammar: Catalan number CnC_n of trees.

Traps and GATE patterns

Connections

Ambiguity is also studied as a property of grammars in ambiguity in grammars. The transformed expression grammar is the one used to build the FIRST and FOLLOW sets (FIRST and FOLLOW) and the table of the LL(1) parser. Bottom-up parsers (LR parsing) accept the left-recursive layered grammar directly. The tree shape after removing left recursion is repaired by semantic actions, see translation schemes.

PYQs

8 previous year questions from your book. I re-solved each one myself (6 by running or simulating, 2 by reasoning only); the book's key is shown next to my answer. All PYQs

GATE 2025 · MSQQ4 · page 256 of the book
Consider two grammars G1 and G2 with the
production rules given below:

G1: S → if E then S | if E then S else S | a

       E → b

G2: S → if E then S | M

       M → if E then M else S | c

       E → b

where if, then, else, a, b, c are the terminals.

Which of the following option(s) is/are CORRECT?
  • (a)G1 is not LL(1) and G2 is LL(1).
  • (b)G1 is LL(1) and G2 is not LL(1).
  • (c)G1 and G2 are not LL(1).
  • (d)G1 and G2 are ambiguous.
GATE 2018 · MCQQ16 · page 258 of the book
Consider the following parse tree for the expression
a#b$c$d#e#f, involving two binary operators $ and #.

Which one of the following is correct for the given
parse tree?
  • (a)$ has higher precedence and is left associative; # is right associative
  • (b)# has higher precedence and is left associative; $ is right associative
  • (c)$ has higher precedence and is left associative; # is left associative
  • (d)# has higher precedence and is right associative; $ is left associative
GATE 2017 · MCQQ21 · page 259 of the book
Consider the following expression grammar G:

E → E - T | T

T → T + F | F

F → (E) | id

Which of the following grammars is not left
recursive, but is equivalent to G?
  • (a)E → E – T | T T → T + F | F F → (E) | id
  • (b)E →T E' E'→ – TE' | ε T → T + F | F F → (E) | id
  • (c)E → TX X →–TX | ε T → FY Y → +FY | ε F → (E) | id
  • (d)E → TX | (TX) X → –TX | +TX | ε T → id
GATE 2016 · MCQQ22 · page 259 of the book
Which one of the following grammars is free from
left recursion?
  • (a)S → AB A → Aa | b B → c
  • (b)S → A b | B b | C A → Bd | ε B →e COMPILER DESIGN
  • (c)S→Aa | B A→B b | Sc | ε B→ d
  • (d)S→Aa | Bb | c A→B d | ε B→ d | ε
GATE 2014 · MCQQ28 · page 261 of the book
Consider the grammar defined by the following
production rules, with two operators * and +

S → T * P

T → U | T * U

P → Q + P | Q

Q → Id

U → Id

Which one of the following is TRUE?
  • (a)+ is left associative, while * is right associative
  • (b)+ is right associative, while * is left associative
  • (c)Both + and * are right associative
  • (d)Both + and * are left associative
GATE 2011 · MCQQ33 · page 262 of the book
Consider two binary operators '↑' and '↓' with the
precedence of operator ↓ being lower than that of the
operator ↑. Operator ↑ is right associative while
operator ↓ is left associative. Which one of the
following represents the parse tree for expression
(7↓3↑4↑3↓2) ?
  • (a)
  • (b)
  • (c)
  • (d)COMPILER DESIGN
GATE 2005 · MCQQ38 · page 263 of the book
The grammar A → AA | (A) | ε is not suitable for
predictive-parsing because the grammar is
  • (a)ambiguous
  • (b)left-recursive
  • (c)right-recursive
  • (d)an operator-grammar
GATE 2005 · MCQQ40 · page 263 of the book
Consider the context-free grammar

E → E + E
E → (E * E)
E → id

where E is the starting symbol, the set of terminals is
{id, (+,),*}, and the set of non-terminals is {E}.

For the terminal string id + id + id + id, how many
parse trees are possible?

COMPILER DESIGN
  • (a)5
  • (b)4
  • (c)3
  • (d)2

Self-check

Question 1

Is S→SS∣aS \to S S \mid a ambiguous? Give the evidence.

Show answer

Yes. The string aaaaaa has two trees: S→SSS \to S S with the left SS expanded to SSS S (grouping (aa)a(aa)a) and with the right SS expanded to SSS S (grouping a(aa)a(aa)).

Question 2

Remove the left recursion: A→Ab∣cA \to A b \mid c.

Show answer

A→cA′A \to c A' and A′→bA′∣εA' \to b A' \mid \varepsilon.

Question 3

How many parse trees does E→E+E∣E∗E∣idE \to E + E \mid E * E \mid \text{id} give for id+id+id+id\text{id} + \text{id} + \text{id} + \text{id}?

Show answer

Three operators, so the Catalan number C3=5C_3 = 5.

Question 4

Does left factoring make an ambiguous grammar unambiguous?

Show answer

No: it changes the grammar but the language and the ambiguity of strings remain; the dangling else is still ambiguous after factoring.

Revision card

One-screen revision

  • Ambiguous: two parse trees (two leftmost derivations) for some string; undecidable in general.
  • Precedence by layers (tighter operator deeper), associativity by recursion side; dangling else by matched and unmatched statements.
  • A→Aα∣βA \to A\alpha \mid \beta gives A→βA′A \to \beta A', A′→αA′∣εA' \to \alpha A' \mid \varepsilon; use the ordering algorithm for indirect recursion.
  • Left factor common prefixes: A→αA′A \to \alpha A'.
  • Left recursion breaks top-down parsers, not LR. Factoring does not remove ambiguity.

References

  • ·Aho, Lam, Sethi, Ullman, Compilers: Principles, Techniques, and Tools (2nd edition), Chapter 4 Syntax Analysis (4.2 context-free grammars, ambiguity, 4.3 writing a grammar: eliminating ambiguity, left recursion, left factoring)
  • ·Hopcroft, Motwani, Ullman, Introduction to Automata Theory, Languages, and Computation, Chapter 5 Context-Free Grammars and Languages (ambiguity)

Verification

The two derivations and the number of parse trees are computed by exhaustive enumeration of leftmost derivations and re-counted with an independent span-counting method (scripts/enum-checks/cd_grammar.py): the flat expression grammar has a Catalan number of trees for n operators, the layered grammar never more than one. Left recursion removal and left factoring are implemented in scripts/cd_lib.py and their results on the grammars quoted below were compared with the page text; each transformed grammar was checked to generate the same strings (up to length 7) as the original. The statement that ambiguity of a general CFG is undecidable is a standard theorem quoted from textbooks, not machine-checked. SECOND PASS (2026-11-02, done by the assistant, not a human check): every Self-check question was solved before the printed answer was read and all agreed; the definitions, worked examples, cheat box and traps were read claim by claim and the numbers re-derived by hand or by a small script (token counts, FIRST and FOLLOW sets, LL(1) tables and moves, LR item sets, state counts and parses, operator-precedence values, attribute evaluation and printing schemes, activation-record counts and access links, parameter-passing results, three-address code, jumping and backpatched code, leaders and blocks, value numbering and DAGs, gen/kill and data flow sets, Sethi-Ullman labels and live ranges); long C programs were not re-read line by line (they are compiled and compared by npm run verify:c, and their printed outputs were checked against the prose); tables and animations are machine output and were read, not re-run; No other defect found. Status raised to self-checked; verified needs a textbook or human check.

last verified: never