Algorithm Search⌘K

Proofs: Left recursion elimination algorithm

These are the human proofs of Left recursion elimination algorithm, at full length.

PREPARE followed by PAULL keeps the language and removes all left recursion full

This proof shows: correctness.

Statement. Let G=(V,Σ,R,S)G = (V, \Sigma, R, S) be any grammar, and let G′G' be the result of PREPARE, then PAULL, then the new start S0→S∣εS_0 \to S \mid \varepsilon when ε∈L(G)\varepsilon \in L(G). Then L(G′)=L(G)L(G') = L(G), and no nonterminal XX of G′G' satisfies X⇒+XγX \Rightarrow^+ X \gamma.

Throughout, LK(X)L_K(X) is the set of terminal strings derived from XX in the grammar KK, and trees are complete parse trees.

Step 1 (PREPARE). Let HH be the grammar after line P4. We show that LH(S)=L(G)∖{ε}L_H(S) = L(G) \setminus \{\varepsilon\}, that HH has no ε\varepsilon-production, that every nonterminal with a production derives a terminal string, and that no nonterminal satisfies X⇒+XX \Rightarrow^+ X in HH.

  • Lines P1 and P3 drop only productions that use a symbol deriving no terminal string. No complete tree uses such a production, so L(X)L(X) is unchanged for every remaining XX.
  • Line P2 is epsilon-production elimination, which gives L(X)∖{ε}L(X) \setminus \{\varepsilon\} for each XX and no ε\varepsilon-production.
  • Without ε\varepsilon-productions a step never shortens a sentential form, so a derivation X⇒+XX \Rightarrow^+ X goes through strings of length 1 only, and uses only unit productions Y→ZY \to Z. Thus such cycles are exactly the cycles of the unit graph, with an edge Y→ZY \to Z for each unit production. Line P4 renames every nonterminal YY to the representative ρ(Y)\rho(Y) of its strongly connected component in this graph and drops the productions ρ→ρ\rho \to \rho. Claim: for every XX, the new grammar derives ww from ρ(X)\rho(X) exactly when the old one derives ww from XX. From old to new, rename every node label of an old tree by ρ\rho and remove each node that now uses ρ→ρ\rho \to \rho, putting its child in its place. From new to old, we show by induction on the size of a new tree tt with root ρ(X)\rho(X) that, for every X′X' with ρ(X′)=ρ(X)\rho(X') = \rho(X), there is an old tree with root X′X' and the same yield: the root of tt uses ρ(X)→ρ(ψ)\rho(X) \to \rho(\psi) for some old production Z→ψZ \to \psi with ρ(Z)=ρ(X)\rho(Z) = \rho(X); in the old grammar X′⇒∗ZX' \Rightarrow^* Z by unit productions, because X′X' and ZZ lie in one component; apply Z→ψZ \to \psi and replace each child subtree by the old tree given by the induction hypothesis for the corresponding symbol of ψ\psi. After the renaming the unit graph is the condensation of the old one without loops, so it is acyclic, and HH has no derivation X⇒+XX \Rightarrow^+ X. Renaming creates no ε\varepsilon-production and no unproductive symbol.

Line P5 records ε∈L(G)\varepsilon \in L(G) before line P2 removes it, and S0S_0 adds it back at the end.

Step 2 (substitution keeps the language). Let KK have a production p=A→Bγp = A \to B \gamma with B≠AB \ne A, and let K′K' be KK with pp replaced by A→δγA \to \delta \gamma for every production B→δB \to \delta of KK. Then LK′(X)=LK(X)L_{K'}(X) = L_K(X) for every XX. A step A→δγA \to \delta \gamma of K′K' is the two steps A→BγA \to B \gamma, B→δB \to \delta of KK. Conversely, take a KK-tree and a node that uses pp. Its first child is labelled BB and is an inner node using some B→δB \to \delta; this production is not pp, because B≠AB \ne A, and it is still in K′K', because the productions of BB do not change. Replace the two nodes by one node AA using A→δγA \to \delta \gamma, whose children are the children of the BB node followed by the other children of the AA node. The yield does not change, and the number of nodes using pp drops by one, so induction on this number gives a K′K'-tree.

Lines L3 to L5 apply this step once for each replaced production, with A=AiA = A_i and B=AjB = A_j, j<ij < i, while RjR_j stays fixed, so every set L(X)L(X) is unchanged.

Step 3 (the direct step keeps the language). Let KK have the productions A→Aα1∣⋯∣Aαp∣β1∣⋯∣βqA \to A \alpha_1 \mid \cdots \mid A \alpha_p \mid \beta_1 \mid \cdots \mid \beta_q, where no βk\beta_k starts with AA, and let K′K' replace them by A→βkA′A \to \beta_k A' and A′→αlA′∣εA' \to \alpha_l A' \mid \varepsilon, with A′A' new. Then LK′(X)=LK(X)L_{K'}(X) = L_K(X) for every nonterminal XX of KK. In a KK-tree, take a node AA that is not the first child of a node using some A→AαlA \to A \alpha_l, and follow its first children down while they use productions A→Aαl1A \to A \alpha_{l_1}, A→Aαl2A \to A \alpha_{l_2}, ..., A→AαltA \to A \alpha_{l_t}; the last AA on this spine uses some A→βkA \to \beta_k. The spine has yield y(βk) y(αlt)⋯y(αl1)y(\beta_k) \, y(\alpha_{l_t}) \cdots y(\alpha_{l_1}), where yy denotes the yields of the subtrees of these symbols. Replace it by the node A→βkA′A \to \beta_k A' and the chain A′→αltA′A' \to \alpha_{l_t} A', ..., A′→αl1A′A' \to \alpha_{l_1} A', A′→εA' \to \varepsilon, which has the same yield. Doing this for the topmost such spine and then, by induction on size, inside the subtrees of βk\beta_k and of the α\alphas gives a K′K'-tree. Conversely, A′A' occurs only at the right end of the new productions, so in a K′K'-tree every A′A' node lies on a chain that hangs from a node A→βkA′A \to \beta_k A' and ends with A′→εA' \to \varepsilon; the inverse rewriting turns this chain back into a left spine.

By Steps 1 to 3, LG′(S)=LH(S)L_{G'}(S) = L_H(S) after the loop, so L(G′)=L(G)L(G') = L(G) once S0S_0 is added.

Step 4 (three invariants). Call A1,…,AmA_1, \ldots, A_m the original nonterminals and the Ak′A_k' the primed ones. We show that the following hold before round 1 and after every substitution and every direct step:

  • (P) every production of an original nonterminal is nonempty and starts with a terminal or an original nonterminal;
  • (U) if an original XX has a production X→YπX \to Y \pi with YY original and π\pi a string of primed symbols, then X⇒+YX \Rightarrow^+ Y in HH by unit productions;
  • (I) after round ii, every production of AkA_k with k≤ik \le i starts with a terminal or with some AlA_l, l>kl > k.

Before round 1 there are no primed symbols, so (P) is the absence of ε\varepsilon-productions in HH and (U) says that X→YX \to Y is a unit production of HH.

Substitution. The production Ai→AjγA_i \to A_j \gamma becomes Ai→δγA_i \to \delta \gamma with Aj→δA_j \to \delta. By (P) for AjA_j, δ\delta is nonempty and starts with a terminal or an original, so (P) holds. If δγ=Yπ\delta \gamma = Y \pi with YY original and π\pi primed, then δ=Yπ1\delta = Y \pi_1 and γ=π2\gamma = \pi_2 with π1,π2\pi_1, \pi_2 primed. (U) for Ai→AjγA_i \to A_j \gamma gives Ai⇒+AjA_i \Rightarrow^+ A_j, and (U) for Aj→Yπ1A_j \to Y \pi_1 gives Aj⇒+YA_j \Rightarrow^+ Y, both by unit productions of HH; so Ai⇒+YA_i \Rightarrow^+ Y and (U) holds.

Direct step. The new productions of AiA_i are Ai→βkAi′A_i \to \beta_k A_i', where Ai→βkA_i \to \beta_k was a production before the step. By (P), βk\beta_k is nonempty and starts with a terminal or an original, so (P) holds. If βkAi′=Yπ\beta_k A_i' = Y \pi with π\pi primed, then βk=Yπ1\beta_k = Y \pi_1 with π1\pi_1 primed, and (U) for Ai→βkA_i \to \beta_k gives Ai⇒+YA_i \Rightarrow^+ Y. The productions of Ai′A_i' are not productions of an original, so (P) and (U) say nothing about them.

Invariant (I). Rounds before and after round ii do not change the productions of AkA_k, k<ik < i. In round ii, after iteration jj of line L3, no production of AiA_i starts with A1,…,AjA_1, \ldots, A_j: iteration jj replaces each production that starts with AjA_j by productions that start with δ\delta, and by (I) for k=j<ik = j < i, δ\delta starts with a terminal or with AlA_l, l>jl > j. So after line L5 every production of AiA_i starts with a terminal or with AlA_l, l≥il \ge i. Lines L6 to L9 replace those that start with AiA_i, and the new productions βkAi′\beta_k A_i' start with the first symbol of βk\beta_k, which is a terminal or an AlA_l with l>il > i.

The direct step is well defined. At line L6 there is at least one β\beta: by Steps 2 and 3, L(Ai)L(A_i) is still LH(Ai)L_H(A_i), which is not empty; if every production of AiA_i started with AiA_i, the leftmost path of any tree with root AiA_i would never end. Each αl\alpha_l is not a string of primed symbols, and in particular not empty: otherwise (U) applied to Ai→AiαlA_i \to A_i \alpha_l gives Ai⇒+AiA_i \Rightarrow^+ A_i in HH, which Step 1 excludes.

Step 5 (nullable symbols). In G′G' every primed symbol is nullable, by Ak′→εA_k' \to \varepsilon, and no original symbol is nullable. Suppose some original is; take one, XX, with a tree of yield ε\varepsilon of least height. By (P), XX uses a production that starts with a terminal, which cannot vanish, or with an original YY, whose subtree has yield ε\varepsilon and smaller height. Both contradict the choice of XX.

Step 6 (no left recursion). Define the left-corner graph of G′G': an edge X→YX \to Y whenever G′G' has a production X→μYνX \to \mu Y \nu with μ\mu nullable. If X⇒+XγX \Rightarrow^+ X \gamma, take a tree with root XX and yield XγX \gamma and the path from the root to the leaf XX at the left end of the yield. Every sibling to the left of a node on this path has yield ε\varepsilon, so every edge of the path is an edge of the graph, and the path is a closed walk of length at least 1 through XX. So it suffices to show that the graph has no cycle.

  • Edges from an original AkA_k. By (I) the first symbol of each production of AkA_k is a terminal or an AlA_l with l>kl > k, and by Step 5 it is not nullable. So the only edges from AkA_k go to originals AlA_l with l>kl > k.
  • Edges from a primed Ak′A_k'. Its productions are Ak′→εA_k' \to \varepsilon and Ak′→αAk′A_k' \to \alpha A_k' with α\alpha fixed in round kk; they never change afterwards, since later rounds rewrite only productions of originals. At that time the primed symbols are Al′A_l' with l<kl < k, so α\alpha contains no Ak′A_k'. By Step 4, α\alpha contains a terminal or an original; the left corners of αAk′\alpha A_k' are the symbols of α\alpha up to the first of these. So the edges from Ak′A_k' go to some Al′A_l' with l<kl < k and to at most one original or terminal, and never to Ak′A_k'.
  • Edges from S0S_0 go to SS, and no edge enters S0S_0, which occurs on no right side.

A cycle that contains an original stays among originals, because no edge leads from an original to a primed symbol, and then the indices strictly increase along it, which is impossible. A cycle of primed symbols only has strictly decreasing indices, which is also impossible. So the graph is acyclic and G′G' has no left-recursive nonterminal.

Termination. PREPARE does a bounded amount of work, line P2 creating at most 2r2^r versions of a production with rr nullable symbols. The main loop does mm rounds of at most m−1m - 1 substitutions, each over a finite set of productions. So the algorithm stops. ■\blacksquare

Back to Left recursion elimination algorithm