Introduction

A context-free grammar written to describe a language is often unsuitable for a parser. An ambiguous grammar gives a parser two trees to choose from. A left-recursive grammar sends a top-down parser into an infinite loop. Two alternatives that begin with the same symbols force a top-down parser to guess. This note collects the three standard rewrites that fix these problems while keeping the language the same: eliminating ambiguity, eliminating left recursion, and left factoring.

Each rewrite preserves the set of strings but changes the shape of the parse trees. That matters later, because translations attached to the grammar (for example, evaluating left-associative subtraction) must then be adjusted to the new shape.

Prerequisites

Core concepts

Notation used in all Compiler Design notes. Upper-case letters and names such as E, T, stmt are nonterminals; lower-case letters, operator symbols and bold-face names such as id are terminals; Greek letters α,β,γ\alpha, \beta, \gamma are strings of grammar symbols (possibly empty); ε\varepsilon is the empty string. The first production's head is the start symbol. A vertical bar separates alternatives.

TermDefinition
Immediately left-recursiveSome production has the form A→AαA \to A\alpha
Left-recursiveA⇒+AαA \Rightarrow^{+} A\alpha for some α\alpha: AA can derive a sentential form that starts with AA in one or more steps
Indirect left recursionLeft recursion through other nonterminals, for example S→AaS \to A a, A→ScA \to S c
Common prefixTwo alternatives A→αβ1∣αβ2A \to \alpha\beta_1 \mid \alpha\beta_2 with α≠ε\alpha \ne \varepsilon
Ambiguous grammarSome string has two different parse trees (equivalently, two leftmost derivations)

How it works

Eliminating ambiguity by precedence levels

The grammar E→E+E∣E∗E∣(E)∣idE \to E + E \mid E * E \mid ( E ) \mid \textbf{id} is ambiguous: id + id * id has two parse trees, one grouping id * id first and one grouping id + id first. With only +, the string id + id + id + id has 5 parse trees, the Catalan number C3C_3, one per way of bracketing three operators.

The fix introduces one nonterminal per precedence level, lowest precedence nearest the start symbol, and chooses left or right recursion per operator to fix associativity:

Text
E -> E + T | T        (+ lowest precedence, left-associative)
T -> T * F | F        (* higher precedence, left-associative)
F -> ( E ) | id

Now id + id * id has exactly one parse tree, with * below +.

Associativity rule. A left-recursive production E→E op TE \to E \text{ op } T makes op left-associative (the leftmost operator is deepest in the tree, so it is applied first). A right-recursive production E→T op EE \to T \text{ op } E makes it right-associative, as used for exponentiation P -> B ^ P | B. Associativity is read from where the recursive nonterminal sits relative to the operator, not from the parser that will be used.

Reading an unusual grammar. In

Text
E -> T * E | T
T -> T - F | F
F -> num

- is on the lower level TT, so it binds tighter than *; - is left-associative (left recursion in TT) and * is right-associative (right recursion in EE). The string 8 - 2 - 1 * 3 * 2 - 1 has exactly one parse tree. First split at the * signs into the TT-pieces 8 - 2 - 1, 3 and 2 - 1; each piece groups to the left, and the pieces combine from the right:

((8−2)−1)∗(3∗(2−1))=5∗3=15.((8 - 2) - 1) * (3 * (2 - 1)) = 5 * 3 = 15 .

With the usual precedences the same string would evaluate to 8−2−6−1=−18 - 2 - 6 - 1 = -1.

The dangling else

The grammar S -> i E t S | i E t S e S | a, E -> b (with i for if, t for then, e for else) is ambiguous: i b t i b t a e a has two trees, one attaching the else to the inner if and one to the outer. Languages choose "match each else with the closest unmatched then". An unambiguous grammar for that rule separates matched statements (every then has its else) from open ones:

Text
S -> M | O
M -> i E t M e M | a
O -> i E t S | i E t M e O
E -> b

It generates the same strings, and i b t i b t a e a now has exactly one tree, with the else attached to the inner if. Parser generators usually keep the short ambiguous grammar and resolve the conflict in favour of shifting else, which gives the same grouping.

Eliminating immediate left recursion

A top-down parser expands the leftmost nonterminal. With A→AαA \to A\alpha it would expand AA to AαA\alpha, then to AααA\alpha\alpha, without ever consuming input. The cure rewrites the recursion to the right.

Group the AA-productions as

A→Aα1∣Aα2∣⋯∣Aαm∣β1∣β2∣⋯∣βn,A \to A\alpha_1 \mid A\alpha_2 \mid \cdots \mid A\alpha_m \mid \beta_1 \mid \beta_2 \mid \cdots \mid \beta_n,

where no βj\beta_j begins with AA. Every string derived from AA is some βj\beta_j followed by any sequence of αi\alpha_i's. Replace them by

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

with a new nonterminal A′A'. Applied to the expression grammar:

Text
E  -> T E'
E' -> + T E' | eps
T  -> F T'
T' -> * F T' | eps
F  -> ( E ) | id

The two explicitly parenthesised expression grammars, the precedence grammar and this left-recursion-free grammar, generate exactly the same strings (257 token strings of length at most 9 agree). This rewritten grammar is not left-recursive and is LL(1).

Precondition. If every αi\alpha_i were ε\varepsilon (a production A→AA \to A), the rewrite would be meaningless; such cycles are removed first. ε\varepsilon-productions elsewhere are allowed in the immediate case.

Example: several alternatives on each side. S→Sa∣Sb∣c∣dS \to S a \mid S b \mid c \mid d has α1=a\alpha_1 = a, α2=b\alpha_2 = b, β1=c\beta_1 = c, β2=d\beta_2 = d:

Text
S  -> c S' | d S'
S' -> a S' | b S' | eps

Both grammars generate (c∣d)(a∣b)∗(c \mid d)(a \mid b)^{*}.

Example: one β\beta is ε\varepsilon. In A→Ac∣Aad∣bd∣εA \to A c \mid A a d \mid b d \mid \varepsilon, the non-recursive alternatives are β1=bd\beta_1 = b d and β2=ε\beta_2 = \varepsilon. The ε\varepsilon alternative does not disappear; it becomes A→A′A \to A':

Text
A  -> b d A' | A'
A' -> c A' | a d A' | eps

Both generate (bd∣ε)(c∣ad)∗(b d \mid \varepsilon)(c \mid a d)^{*}. Dropping A→A′A \to A' would lose every string that does not start with b d, for example c and ad.

Eliminating indirect left recursion

The general algorithm orders the nonterminals A1,A2,…,AnA_1, A_2, \ldots, A_n and makes every production Ai→AjγA_i \to A_j\gamma satisfy j>ij > i.

Text
ELIMINATE-LEFT-RECURSION(G)
    order the nonterminals A1, A2, ..., An
    for i <- 1 to n
        for j <- 1 to i - 1
            replace each production Ai -> Aj gamma by
                Ai -> delta1 gamma | ... | deltak gamma,
                where Aj -> delta1 | ... | deltak are the current Aj-productions
        eliminate immediate left recursion among the Ai-productions

Precondition: the grammar has no cycles (A⇒+AA \Rightarrow^{+} A) and no ε\varepsilon-productions; with ε\varepsilon-productions, hidden left recursion can survive the substitution. Time: the substitution step can multiply the number of productions, so the output may be exponentially larger than the input in the worst case.

Worked example. Order S,AS, A in

Text
S -> A a | b
A -> S c | d

SS has no immediate left recursion. For AA, substitute the SS-productions into A→ScA \to S c: A→Aac∣bc∣dA \to A a c \mid b c \mid d. Now remove the immediate left recursion with α=ac\alpha = a c, β1=bc\beta_1 = b c, β2=d\beta_2 = d:

Text
S  -> A a | b
A  -> b c A' | d A'
A' -> a c A' | eps

The original grammar is left-recursive (S⇒Aa⇒ScaS \Rightarrow A a \Rightarrow S c a); the result is not, and both generate the same strings (all strings up to length 10 agree).

Hidden left recursion. In S -> A S b | c, A -> a | eps no production starts with S, yet S⇒ASb⇒SbS \Rightarrow A S b \Rightarrow S b because AA is nullable. This grammar is left-recursive. Questions that ask "is the grammar left-recursive?" test exactly this.

Left factoring

When two alternatives share a non-empty prefix α\alpha, a predictive parser cannot choose between them by looking at the next token. Left factoring delays the choice until the prefix has been read:

A→αβ1∣αβ2∣⋯∣αβn∣γ⟹A→αA′∣γ,A′→β1∣β2∣⋯∣βn.A \to \alpha\beta_1 \mid \alpha\beta_2 \mid \cdots \mid \alpha\beta_n \mid \gamma \quad\Longrightarrow\quad A \to \alpha A' \mid \gamma, \qquad A' \to \beta_1 \mid \beta_2 \mid \cdots \mid \beta_n .

Take α\alpha to be the longest prefix common to two or more alternatives, and repeat until no two alternatives of any nonterminal share a prefix.

Example 1 (dangling else). S -> i E t S | i E t S e S | a has common prefix i E t S:

Text
S  -> i E t S S' | a
S' -> e S | eps
E  -> b

The language is unchanged, but the grammar is still ambiguous and still not LL(1): with e as the next token, S′S' may either take e S or derive ε\varepsilon (because e can follow S′S'). Left factoring removes guessing caused by common prefixes; it cannot remove ambiguity.

Example 2 (repeated factoring). A -> a b c | a b d | a e. The longest prefix shared by two alternatives is a b, but a is shared by all three. Factoring a first and then b:

Text
A   -> a A'
A'  -> b A'' | e
A'' -> c | d

Important properties and observations

  • Language preserved, trees changed. All three rewrites keep the language. Removing left recursion turns left-leaning trees into right-leaning ones; an attribute rule that computed left-associative subtraction on the old grammar must be rewritten with inherited attributes on the new one (see the note Syntax-Directed Translation Schemes in this subject).
  • Independent problems. Removing left recursion does not remove ambiguity, and left factoring does not remove left recursion. An ambiguous grammar is never LL(1) or LR(1), whatever else is done to it.
  • Necessary, not sufficient. A grammar that is unambiguous, free of left recursion and left-factored may still fail to be LL(1). The test is the LL(1) condition on FIRST and FOLLOW sets.
  • Bottom-up parsers do not need these rewrites. LR parsers handle left recursion well (left recursion even keeps the LR stack short); only ambiguity matters to them.
  • Inherent ambiguity. Some context-free languages have no unambiguous grammar at all; no rewrite can help (see the Theory of Computation note on context-free grammars).

Common misconceptions.

  • "Right recursion is a problem for top-down parsing." It is not; only left recursion is.
  • "Left factoring makes a grammar unambiguous." It does not: the factored dangling-else grammar is still ambiguous.
  • "A→βA′A \to \beta A', A′→αA′∣εA' \to \alpha A' \mid \varepsilon is a different language." It is the same language βα∗\beta\alpha^{*}, written with right recursion.
  • "Removing left recursion from A→Aα∣εA \to A\alpha \mid \varepsilon gives A′→αA′∣εA' \to \alpha A' \mid \varepsilon only." AA itself must still derive A′A', as in A→A′A \to A'.

GATE examination perspective

  • Apply the rewrite. Given A→Aα∣βA \to A\alpha \mid \beta, write A→βA′A \to \beta A', A′→αA′∣εA' \to \alpha A' \mid \varepsilon. Check each β\beta carefully: every non-left-recursive alternative gets A′A' appended.
  • Is the grammar left-recursive? Look for indirect and hidden left recursion through nullable nonterminals, not only for A→A…A \to A\ldots.
  • Which rewrite for which parser. Left-recursion removal and left factoring prepare a grammar for top-down (LL) parsing. They are not needed for LR parsing.
  • Ambiguity questions. Count parse trees for a short string; with one binary operator and no precedence, nn operators give CnC_n trees (5 for three operators). A grammar with two parse trees for one string is ambiguous, even if all other strings have one tree.
  • Associativity and precedence from a grammar. Lower precedence nearer the start symbol; left recursion means left-associative, right recursion right-associative. Questions sometimes define unusual grammars where + binds tighter than *; read the levels, not your habits.
  • Language equality. Options that change the language (dropping an alternative, forgetting ε\varepsilon in A′A') are the usual wrong answers.
  • The ε\varepsilon alternative of a left-recursive nonterminal. This is a β\beta: A→Aα∣εA \to A\alpha \mid \varepsilon becomes A→A′A \to A', A′→αA′∣εA' \to \alpha A' \mid \varepsilon (equivalently A→αA∣εA \to \alpha A \mid \varepsilon after renaming).
  • Evaluate with the grammar's precedences. For an unusual grammar, split the string at the lowest-level operator first, then group each piece by its own associativity.

Summary

Sources

  1. A. V. Aho, M. S. Lam, R. Sethi, J. D. Ullman, Compilers, Principles, Techniques, and Tools, 2nd ed., Pearson Addison-Wesley, 2007: Section 2.2.5 (associativity of operators), Section 2.2.6 (precedence of operators), Section 4.3.2 (eliminating ambiguity, the dangling else), Section 4.3.3 (elimination of left recursion), Section 4.3.4 (left factoring).

Next steps