Professional Documents
Culture Documents
S → XX | Y
Recall: A CFG is left-recursive if it includes a variable A s.t. X → aXb | ǫ
+ Y → aY b | Z
A⇒ Aα .
Z → bZa | ǫ
Notice that
∗ ∗ ∗ ∗
S⇒ ǫ X⇒ ǫ Y ⇒ ǫ Z⇒ ǫ
We eliminate left-recursion in three steps.
Hence, all the variables in this grammar are what we will call
• eliminate ǫ-productions (impossible to generate ǫ!) “nullable.” So in order to eliminate the ǫ-productions in this
grammar, we must alter the grammar to take into account the
+
• eliminate cycles (A ⇒ A)
fact that instances of these variables in a derivation may
• eliminate left-recursion eventually be replaced by ǫ. So, for instance, we will replace
Z → bZa | ǫ
with
So we’ve got some constructions to learn.
Z → bZa | ba .
After elimination of ǫ-productions, we obtain
Let’s try an example of eliminating ǫ-productions before we
specify a construction. . . S → XX | X | Y
X → aXb | ab
Y → aY b | ab | Z
Z → bZa | ba
1 2
Eliminating ǫ-productions ∗
A is nullable if A ⇒ ǫ.
3 4
Eliminating ǫ-productions can greatly increase the size of a Eliminating cycles
grammar.
A grammar has a cycle if there is a variable A s.t.
Example Eliminating ǫ-productions from
+
A⇒ A.
S → A1A2 · · · An
A1 → ǫ We’ll call such variables cyclic.
A2 → ǫ
... If a grammar has no ǫ-productions, then all cycles can be
An → ǫ eliminated from G without affecting the language generated,
using a construction we will specify in a moment.
increases the number of productions from n + 1 to 2n − 1.
Let’s try an example first. Consider the grammar with
productions
S → X | Xb | SS
What about ambiguity?
X → S|a
Claim If G is unambiguous, so is Gǫ . + +
We have S ⇒ S and X ⇒ X.
S → a | Xb | SS
X → Xb | SS | a
5 6
Given a CFG G = (V, Σ, S, P ), the main step in the cycle Replace the set P of productions with the set Pc of
elimination algorithm is to replace the set P of productions productions obtained from P by replacing
with the set Pc of productions obtained from P by replacing
• each production A → B where B is cyclic
• each production A → B where B is cyclic • with new productions A → α s.t. α is not a cyclic variable
∗
• with new productions A → α s.t. α is not a cyclic variable and there is a production C → α s.t. B ⇒ C.
∗
and there is a production C → α s.t. B ⇒ C.
Let’s consider an example illustrating the importance of
The resulting CFG is Gc = (V, Σ, S, Pc).
requiring that there be no ǫ-productions.
Which productions will be replaced? (BTW What does the ǫ-elimination algorithm do to this
grammar?)
With what?
7 8
Eliminating “immediate” left recursion If
A → Aα1 | Aα2 | · · · | Aαm | β1 | β2| · · · | βn
Let’s begin with an easy example, already considered: represents all the A-productions of the grammar, and no βi
begins with A, then we can replace these A-productions by
A → Ab | b
A → β1A′ | β2 A′| · · · | βnA′
This grammar is left-recursive, since A′ → α1A′ | α2 A′ | · · · | αm A′ | ǫ
+
A⇒ Ab .
If our grammar has S-productions
In this case, we can eliminate left recursion as follows: S → SX | SSb | XS | a
More generally, we can eliminate “immediate” left recursion as Notice that this construction can fail to eliminate
follows. If left-recursion if we have the production
A → Aα1 | Aα2 | · · · | Aαm | β1 | β2| · · · | βn A→A!
represents all the A-productions of the grammar, and no βi For instance,
begins with A, then we can replace these A-productions by A → A | Ab | b
becomes
A → β1A′ | β2 A′| · · · | βnA′
A → bA′
A′ → α1A′ | α2 A′ | · · · | αm A′ | ǫ
A′ → A′ | bA′ | ǫ
9 10
If If
A → Aα1 | Aα2 | · · · | Aαm | β1 | β2| · · · | βn A → Aα1 | Aα2 | · · · | Aαm | β1 | β2| · · · | βn
represents all the A-productions of the grammar, and no βi represents all the A-productions of the grammar, and no βi
begins with A, then we can replace these A-productions by begins with A, then we can replace these A-productions by
Another interesting special case. What if there are no βi’s? Notice also that this construction works only “locally”:
11 12
Here’s an algorithm that eliminates all left-recursion for any Arrange the variables in some order A1 , A2, . . . , An .
CFG without ǫ-productions and without cycles. for i := 1 to n do begin
for j := 1 to i − 1 do begin
Arrange the variables in some order A1 , A2, . . . , An . replace each production of the form Ai → Aj γ
by the productions Ai → δ1 γ | δ2 γ | · · · | δk γ
for i := 1 to n do begin where Aj → δ1 | δ2 | · · · | δk are all the current Aj -productions;
for j := 1 to i − 1 do begin end
replace each production of the form Ai → Aj γ eliminate the immediate left recursion among the Ai -productions;
by the productions Ai → δ1 γ | δ2 γ | · · · | δk γ
end
where Aj → δ1 | δ2 | · · · | δk are all the current Aj -productions;
end So at this point we have grammar
eliminate the immediate left recursion among the Ai -productions;
S → XSS ′ | aS ′
end
S ′ → XS ′ | SbS ′ | ǫ
Consider the grammar X → Xb | Sa | b
S → SX | SSb | XS | a and the next obligation is to replace the production
X → Xb | Sa | b
X → Sa
Let’s order the variables S, X:
with the productions
The first time through we simply eliminate immediate left X → XSS ′ a | aS ′ a .
recursion in S-productions, yielding
We then eliminate immediate left recursion among
S → XSS ′ | aS ′
S ′ → XS ′ | SbS ′ | ǫ X → XSS ′ a | aS ′ a | Xb | b .
X → Xb | Sa | b
13 14
Eliminating immediate left recursion among Let’s look at examples showing that this algorithm can fail if
the grammar has ǫ-productions or cycles.
X → XSS ′ a | Xb | b | aS ′ a
In the simplest case, when there is only one variable, call it X,
yields
the presence of a cycle implies that the grammar includes the
X → bX ′ | aS ′ aX ′
production
X ′ → SS ′ aX ′ | bX ′ | ǫ
X →X.
So the final result is Moreover, the whole left recursion elimination algorithm
S → XSS ′ | aS ′ reduces to elimination of immediate left recursion among
′ ′ ′
S → XS | SbS | ǫ X-productions.
′ ′ ′
X → bX | aS aX
And we have previously observed that our construction for
X ′ → SS ′ aX ′ | bX ′ | ǫ
immediate left recursion elimination is no good in the presence
of X → X.
X→X |a
15 16
S → X|b Here’s an example with an ǫ-production and no cycles:
X → S|a
S → XSa | b
Try ordering S, X. X → ǫ
17 18
So now we can take any grammar and eliminate left-recursion For next time
(in three steps), making it suitable for top-down parsing (with
backtracking!). Read 4.4.
Next time we’ll see how this can be done for top-down parsing.
19 20