Eliminating Left Recursion/Left Factoring and Testing Suitability for Top-Down Parsing
We are given the context-free grammar:
Our goals are to:
- Eliminate left recursion (more precisely: direct and indirect left recursion).
- Eliminate left factoring (to help make decisions with limited lookahead).
- Decide whether these removals make the grammar suitable for top-down parsing (typically meaning an LL-family parser, such as LL(1), that relies on lookahead).
Key definitions used below:
- left recursion
- left factoring
- LL(1) grammar
- top-down parsing
Note: With only as a nonterminal, the analysis is tight: eliminating left recursion may still leave ambiguity and/or FIRST/FOLLOW conflicts that prevent LL(1) parsing.
1) Identify left recursion
In the grammar
both alternatives and begin with (because the first symbol on the right-hand side is ). Therefore is directly left-recursive:
for (and the recursion can repeat because the leading can again expand to or ).
left recursion is present, so a top-down recursive-descent parser without extra machinery would loop.
Eliminate left recursion (direct case)
- 1Step 1
Here A = S. Take α1 = S+ and α2 = S*. The non-recursive alternative is β = a. So S → S(S+) | S(S*) | a.
- 2Step 2
Introduce S' (written as or ).
- 3Step 3
Use the standard construction: S → β S' and S' → α1 S' | α2 S' | ε.
- 4Step 4
α1 = S+ and α2 = S*. So: and .
- 5Step 5
A left-recursion-free grammar is:
(Parentheses indicate grouping; the concatenation order is what matters.)
2) Simplify/interpret the transformed grammar
After elimination we get:
and
This grammar is now free of direct left recursion (a derivation from no longer immediately starts with on the right-hand side; it must start with because of ).
But note an important structural fact:
- The productions for still begin with (because starts with ).
- However, left recursion is assessed per nonterminal: we no longer have a situation where derives strings starting with without first producing a terminal (or without passing through in a way that reintroduces at the front). Here, is anchored by the initial .
So left recursion is removed successfully, but this does not automatically imply LL(1) suitability.
3) Eliminate left factoring
Left factoring is needed when a nonterminal has alternatives with common prefixes (e.g., ).
In the transformed grammar:
- For , alternatives are just one: . No factoring.
- For , alternatives are:
The first two alternatives share prefix (i.e., both start with then immediately continue with either or ). This is not “left factoring” in the classic single-step syntactic-prefix sense until you consider how an LL parser would decide after seeing what it can derive from the prefix .
Concretely:
- An LL parser must decide between and based on lookahead.
- After the parser expands the first and consumes whatever terminals it produces from that , the next terminal is either or .
- Because both alternatives share the same derivation prefix “”, the decision can require lookahead beyond what would be available at the moment you choose the production for .
A typical factoring attempt would introduce intermediate nonterminals to delay the decision until after the part is recognized; but due to the recursive nature of , the grammar still may not become LL(1).
type="tip" title="Left recursion vs. left factoring" content="Eliminating left recursion mainly prevents infinite top-down recursion (termination). Left factoring mainly improves predictability of choices with limited lookahead (often LL(1) decisions). Removing left recursion alone does not guarantee LL(1) suitability."
Does this make the grammar suitable for top-down parsing?
What “suitable for top-down parsing” usually means
For a predictive recursive-descent parser (LL parsing), a common sufficient condition is that the grammar be LL(1), meaning:
- For each nonterminal , the parser can choose the correct production using a single lookahead terminal.
- This is governed by FIRST and FOLLOW sets and constraints that avoid conflicts.
Why left recursion removal is necessary but not sufficient
Even if left recursion is eliminated:
- The grammar can still be ambiguous (multiple parse trees).
- Or it can still produce FIRST/FOLLOW conflicts, where LL(1) cannot decide with limited lookahead.
- Or the factoring is insufficient to make decisions deterministic.
In our transformed grammar:
- always begins with terminal (since ). So .
- But can produce and also can begin with ; since begins with , will also contain .
- Therefore, when the parser is at $S'`, the choice between:
- expanding to
- expanding to
- or using can require lookahead that may not be resolvable with token in all contexts.
Additionally, implies an expression-like structure where operands come from again, and the operator ( or ) occurs after parsing an entire . That tends to increase the need for lookahead or grammar refactoring to ensure deterministic prediction.
Bottom line (justification)
- Left recursion elimination makes the grammar terminating under naive top-down expansion (no immediate loop).
- Left factoring, if performed, may improve decision points, but it does not by itself guarantee LL(1).
- For this grammar, the remaining nondeterminism stems from the fact that alternatives for share a long shared prefix derived from , and also has an option—both of which are classic sources of LL parsing conflicts.
Therefore:
- The resulting grammar is not guaranteed suitable for predictive top-down parsing (LL(1)).
- It may still require either:
- more than one-token lookahead (LL(k) with ),
- or parser techniques like backtracking,
- or a redesign into a conventional expression grammar with explicit precedence/associativity.
From given grammar to parsing suitability
Direct left recursion present
Given grammarcauses infinite expansion for top-down without a guard."
Anchored start
After left-recursion eliminationensures derivations from start with ."
Prediction still may be ambiguous
After left factoring (if applied)has alternatives sharing prefix derived from and includes ."
Likely not LL(1)
LL(1) suitability checkShared-prefix and choices can create FIRST/FOLLOW conflicts."
FAQ: Edge cases and deeper justification
Decision power after transformation (conceptual)
Qualitative view: left recursion affects termination; left factoring affects predictability with lookahead.
Knowledge Check
The grammar is considered left-recursive because it can derive strings starting with which form?
Explore Related Topics
Ambiguity in the Grammar \(S \rightarrow ABA,\; A \rightarrow aA \mid \epsilon,\; B \rightarrow bB \mid \epsilon\)
The grammar (S\rightarrow ABA,;A\rightarrow aA\mid\epsilon,;B\rightarrow bB\mid\epsilon) is ambiguous because the two (A) nonterminals can distribute the same (a)-string in multiple ways, especially when (B) derives (\epsilon).
- It generates the language (L(S)={a^i b^j a^k\mid i,j,k\ge0}=a^*b^a^).
- The shortest string (a) has two distinct left‑most derivations (or parse trees), proving ambiguity.
- Every string (a^n) with (n\ge1) can be split between the two (A) symbols in (n+1) ways, yielding multiple parse trees.
- The ambiguity stems from both (A) producing (a^*) and (B) being able to vanish via (\epsilon).
- An equivalent unambiguous grammar can be constructed, showing the ambiguity is a property of this grammar, not necessarily of the language.
Converting an Arbitrary CFG to an LL(1) Grammar: Correct Option and Why
FIRST/FOLLOW, LL(1) Parsing Table, and LL(1) Determination for a Given CFG