Algorithm Search⌘K

Proofs: LALR lookahead computation

These are the human proofs of LALR lookahead computation, at full length.

Correctness of the DeRemer and Pennello lookahead computation full

This proof shows: correctness.

We prove that the algorithm on the LALR lookahead computation page returns, for every completed item A→ω⋅A \to \omega \cdot of every LR(0) state qq with A≠S′A \ne S', exactly the set of lookaheads that the item has in the canonical LR(1) states whose core is qq.

Notation and assumptions. G=(V,Σ,P,S)G = (V, \Sigma, P, S) is augmented with S′→SS' \to S as production 0, and S′S' occurs on no right side. GG is reduced: every nonterminal is reachable from SS and derives some terminal string. LR(0) states are identified with their kernels; p‾\overline{p} is the closure of pp, and GOTO(p,β)\mathrm{GOTO}(p, \beta) is defined symbol by symbol. For a string γ\gamma and a set MM of terminals, FIRST(γM)\mathrm{FIRST}(\gamma M) is FIRST(γ)\mathrm{FIRST}(\gamma), together with MM when γ⇒∗ε\gamma \Rightarrow^* \varepsilon. T(q)T(q) is the set of terminals tt with GOTO(q,t)\mathrm{GOTO}(q, t) defined. Items A→⋅ωA \to \cdot \omega with A≠S′A \ne S' are never kernel items, and GOTO\mathrm{GOTO} never leads to state 0, whose only kernel item has the dot at position 0.

Part 1: merged lookaheads as a least solution

For a state pp and an item i∈p‾i \in \overline{p}, let M(p,i)M(p, i) be the set of bb such that [i,b][i, b] belongs to some canonical LR(1) state whose core is p‾\overline{p}.

Lemma 1. MM is the least family of sets, indexed by pairs (p,i)(p, i) with i∈p‾i \in \overline{p}, that satisfies

  • (a) $∈M(0,S′→⋅S)\$ \in M(0, S' \to \cdot S);
  • (b) M(GOTO(p,Y),B→βY⋅γ)⊇M(p,B→β⋅Yγ)M(\mathrm{GOTO}(p, Y), B \to \beta Y \cdot \gamma) \supseteq M(p, B \to \beta \cdot Y \gamma);
  • (c) M(p,C→⋅η)⊇FIRST(γ M(p,B→β⋅Cγ))M(p, C \to \cdot \eta) \supseteq \mathrm{FIRST}(\gamma\, M(p, B \to \beta \cdot C \gamma)) for every item B→β⋅Cγ∈p‾B \to \beta \cdot C \gamma \in \overline{p} and every production C→ηC \to \eta.

Proof. Because GG is reduced, every FIRST(γb)\mathrm{FIRST}(\gamma b) is nonempty, so the LR(1) closure adds a dotted production exactly when the LR(0) closure does, and the core of GOTO1(J,Y)\mathrm{GOTO}_1(J, Y) is GOTO(core(J),Y)‾\overline{\mathrm{GOTO}(\mathrm{core}(J), Y)}. Hence MM satisfies (a), since the start state contains [S′→⋅S, $][S' \to \cdot S,\ \$]; (b), since GOTO1(J,Y)\mathrm{GOTO}_1(J, Y) contains [B→βY⋅γ, b][B \to \beta Y \cdot \gamma,\ b] whenever JJ contains [B→β⋅Yγ, b][B \to \beta \cdot Y \gamma,\ b]; and (c), since every LR(1) state is closed. Conversely let M0M_0 be the least solution. Every LR(1) state is built from the start item by GOTO and closure steps, and by induction on the number of steps each of its items [i,b][i, b], in a state with core p‾\overline{p}, has b∈M0(p,i)b \in M_0(p, i): the start item by (a), a kernel item made by GOTO by (b), and an item added by closure by (c). So M⊆M0M \subseteq M_0, and M0⊆MM_0 \subseteq M because MM is a solution. □\square

In the least solution each set is exactly the union of what the rules put into it. Items with the dot at position 0 and A≠S′A \ne S' get lookaheads only from (c), and items with the dot later only from (b). Unrolling (b) along the symbols before the dot gives, for B≠S′B \ne S',

M(q,B→β⋅γ)=⋃{M(p,B→⋅βγ):GOTO(p,β)=q, B→⋅βγ∈p‾},(1)M(q, B \to \beta \cdot \gamma) = \bigcup \{ M(p, B \to \cdot \beta \gamma) : \mathrm{GOTO}(p, \beta) = q,\ B \to \cdot \beta \gamma \in \overline{p} \}, \tag{1}

while M(0,S′→⋅S)=M(GOTO(0,S),S′→S⋅)={$}M(0, S' \to \cdot S) = M(\mathrm{GOTO}(0, S), S' \to S \cdot) = \{\$\}. For a nonterminal transition (p,A)(p, A) define

Fol(p,A)=⋃{FIRST(γ M(p,B→β⋅Aγ)):B→β⋅Aγ∈p‾}.\mathrm{Fol}(p, A) = \bigcup \{ \mathrm{FIRST}(\gamma\, M(p, B \to \beta \cdot A \gamma)) : B \to \beta \cdot A \gamma \in \overline{p} \}.

By (c), M(p,A→⋅ω)=Fol(p,A)M(p, A \to \cdot \omega) = \mathrm{Fol}(p, A) for every production A→ωA \to \omega with A≠S′A \ne S'. An item A→⋅ωA \to \cdot \omega lies in p‾\overline{p} exactly when (p,A)(p, A) is a nonterminal transition: it is added by closure from an item with the dot before AA, and such an item makes GOTO(p,A)\mathrm{GOTO}(p, A) defined. So (1) gives

M(q,A→ω⋅)=⋃{Fol(p,A):(q,A→ω) lookback (p,A)}.(2)M(q, A \to \omega \cdot) = \bigcup \{ \mathrm{Fol}(p, A) : (q, A \to \omega) \text{ lookback } (p, A) \}. \tag{2}

Part 2: the first terminals of a state

For a state qq, let R(q)R(q) be the union of T(q′)T(q') over all states q′q' reachable from qq by moves on nullable nonterminals, qq itself included.

Lemma 2. R(q)=⋃{FIRST(λ):K→κ⋅λ is a kernel item of q}R(q) = \bigcup \{ \mathrm{FIRST}(\lambda) : K \to \kappa \cdot \lambda \text{ is a kernel item of } q \}.

Proof of ⊇\supseteq. We show the stronger claim: for every state q′q' and every item E→ζ⋅η∈q′‾E \to \zeta \cdot \eta \in \overline{q'}, FIRST(η)⊆R(q′)\mathrm{FIRST}(\eta) \subseteq R(q'). Take t∈FIRST(η)t \in \mathrm{FIRST}(\eta) and a derivation η⇒∗tz\eta \Rightarrow^* t z with the fewest steps; induct on that number. Let η=Y1η′\eta = Y_1 \eta'. If Y1=tY_1 = t, then t∈T(q′)⊆R(q′)t \in T(q') \subseteq R(q'). Otherwise Y1Y_1 is a nonterminal, and either tt comes from Y1Y_1, so that Y1→η1Y_1 \to \eta_1 with η1⇒∗tz1\eta_1 \Rightarrow^* t z_1 in fewer steps, and Y1→⋅η1∈q′‾Y_1 \to \cdot \eta_1 \in \overline{q'} gives t∈R(q′)t \in R(q') by induction; or Y1⇒+εY_1 \Rightarrow^+ \varepsilon and η′⇒∗tz\eta' \Rightarrow^* t z in fewer steps, and then the item E→ζY1⋅η′E \to \zeta Y_1 \cdot \eta' lies in q′′‾\overline{q''} for q′′=GOTO(q′,Y1)q'' = \mathrm{GOTO}(q', Y_1), a move on a nullable nonterminal, so t∈R(q′′)⊆R(q′)t \in R(q'') \subseteq R(q') by induction.

Proof of ⊆\subseteq. Let U(q)U(q) be the right side of the lemma. First, T(q)⊆U(q)T(q) \subseteq U(q): an item E→ζ⋅tη∈q‾E \to \zeta \cdot t \eta \in \overline{q} is a kernel item, so t∈U(q)t \in U(q), or it was added by closure from a kernel item K→κ⋅DλK \to \kappa \cdot D \lambda through productions that each begin with the next nonterminal of the chain, so Dλ⇒∗tημλD \lambda \Rightarrow^* t \eta \mu \lambda and t∈FIRST(Dλ)⊆U(q)t \in \mathrm{FIRST}(D \lambda) \subseteq U(q). Second, if CC is nullable and q1=GOTO(q,C)q_1 = \mathrm{GOTO}(q, C), then U(q1)⊆U(q)U(q_1) \subseteq U(q): a kernel item of q1q_1 is B→βC⋅γB \to \beta C \cdot \gamma for some B→β⋅Cγ∈q‾B \to \beta \cdot C \gamma \in \overline{q}. If that item is a kernel item of qq, then FIRST(γ)⊆FIRST(Cγ)\mathrm{FIRST}(\gamma) \subseteq \mathrm{FIRST}(C \gamma) because CC is nullable. If it was added by closure from a kernel item K→κ⋅DλK \to \kappa \cdot D \lambda, then Dλ⇒∗Bμλ⇒Cγμλ⇒∗γμλD \lambda \Rightarrow^* B \mu \lambda \Rightarrow C \gamma \mu \lambda \Rightarrow^* \gamma \mu \lambda, so FIRST(γ)⊆FIRST(γμλ)⊆FIRST(Dλ)\mathrm{FIRST}(\gamma) \subseteq \mathrm{FIRST}(\gamma \mu \lambda) \subseteq \mathrm{FIRST}(D \lambda). By induction along the path, T(q′)⊆U(q′)⊆U(q)T(q') \subseteq U(q') \subseteq U(q) for every q′q' reachable by nullable moves. □\square

Part 3: Read and Follow

For a relation RR on XX and sets F′(x)F'(x), a family FF solves (R,F′)(R, F') if F(x)=F′(x)∪⋃xRyF(y)F(x) = F'(x) \cup \bigcup_{x R y} F(y) for all xx. The family Reach(x)=⋃{F′(y):y reachable from x along R}\mathrm{Reach}(x) = \bigcup \{ F'(y) : y \text{ reachable from } x \text{ along } R \} solves it, and every solution contains it, by induction on the length of a path from xx to yy. So Reach\mathrm{Reach} is the least solution; Part 4 shows that DIGRAPH returns it. Thus line L4 returns the least solution Read of (reads,DR)(\mathrm{reads}, \mathrm{DR}) and line L6 the least solution Follow of (includes,Read)(\mathrm{includes}, \mathrm{Read}).

Lemma 3. Read(p,A)=R(GOTO(p,A))\mathrm{Read}(p, A) = R(\mathrm{GOTO}(p, A)), together with $\$ when (p,A)=(0,S)(p, A) = (0, S).

Proof. A reads path from (p,A)(p, A) is (p,A),(r0,C1),(r1,C2),…,(rk−1,Ck)(p, A), (r_0, C_1), (r_1, C_2), \ldots, (r_{k-1}, C_k) with r0=GOTO(p,A)r_0 = \mathrm{GOTO}(p, A), rj=GOTO(rj−1,Cj)r_j = \mathrm{GOTO}(r_{j-1}, C_j) and every CjC_j nullable, and the terminals in DR along it are T(r0),T(r1),…,T(rk)T(r_0), T(r_1), \ldots, T(r_k). Their union over all such paths is R(r0)R(r_0). The marker $\$ is in DR(x)\mathrm{DR}(x) only for x=(0,S)x = (0, S), the only transition whose target contains S′→S⋅S' \to S \cdot, and no reads path enters (0,S)(0, S) from another node, since that would need a move into state 0. □\square

Lemma 4. Fol\mathrm{Fol} solves (includes,Read)(\mathrm{includes}, \mathrm{Read}), and Fol=Follow\mathrm{Fol} = \mathrm{Follow}.

Proof. Split the union defining Fol(p,A)\mathrm{Fol}(p, A) into the parts FIRST(γ)\mathrm{FIRST}(\gamma) and the parts M(p,B→β⋅Aγ)M(p, B \to \beta \cdot A \gamma) with γ\gamma nullable. The kernel items of GOTO(p,A)\mathrm{GOTO}(p, A) are the items B→βA⋅γB \to \beta A \cdot \gamma for B→β⋅Aγ∈p‾B \to \beta \cdot A \gamma \in \overline{p}, so by Lemmas 2 and 3 the first parts give Read(p,A)\mathrm{Read}(p, A) without $\$. For B=S′B = S' the item is S′→⋅SS' \to \cdot S in state 0 and contributes $\$, which Read contains for (0,S)(0, S). For B≠S′B \ne S' with γ\gamma nullable, (1) writes M(p,B→β⋅Aγ)M(p, B \to \beta \cdot A \gamma) as the union of Fol(p′,B)\mathrm{Fol}(p', B) over the states p′p' with GOTO(p′,β)=p\mathrm{GOTO}(p', \beta) = p and B→⋅βAγ∈p′‾B \to \cdot \beta A \gamma \in \overline{p'}, that is over the (p′,B)(p', B) that (p,A)(p, A) includes. Hence Fol(p,A)=Read(p,A)∪⋃(p,A) includes (p′,B)Fol(p′,B)\mathrm{Fol}(p, A) = \mathrm{Read}(p, A) \cup \bigcup_{(p, A) \text{ includes } (p', B)} \mathrm{Fol}(p', B), and since Follow is the least solution, Follow⊆Fol\mathrm{Follow} \subseteq \mathrm{Fol}.

For the other inclusion define M′M' from Follow: M′(0,S′→⋅S)=M′(GOTO(0,S),S′→S⋅)={$}M'(0, S' \to \cdot S) = M'(\mathrm{GOTO}(0, S), S' \to S \cdot) = \{\$\}, and for B≠S′B \ne S' let M′(q,B→β⋅γ)M'(q, B \to \beta \cdot \gamma) be the union of Follow(p,B)\mathrm{Follow}(p, B) over the states pp with GOTO(p,β)=q\mathrm{GOTO}(p, \beta) = q and B→⋅βγ∈p‾B \to \cdot \beta \gamma \in \overline{p}. Then M′M' satisfies (a) and (b) by its definition. For (c), let B→β⋅Cγ∈p‾B \to \beta \cdot C \gamma \in \overline{p} and C→ηC \to \eta; then M′(p,C→⋅η)=Follow(p,C)M'(p, C \to \cdot \eta) = \mathrm{Follow}(p, C). By Lemmas 2 and 3, FIRST(γ)⊆R(GOTO(p,C))⊆Read(p,C)⊆Follow(p,C)\mathrm{FIRST}(\gamma) \subseteq R(\mathrm{GOTO}(p, C)) \subseteq \mathrm{Read}(p, C) \subseteq \mathrm{Follow}(p, C). If γ\gamma is nullable and B=S′B = S', then (p,C)=(0,S)(p, C) = (0, S) and $∈Read(0,S)\$ \in \mathrm{Read}(0, S); if B≠S′B \ne S', each Follow(p′,B)\mathrm{Follow}(p', B) in M′(p,B→β⋅Cγ)M'(p, B \to \beta \cdot C \gamma) comes from a pair that (p,C)(p, C) includes, so it is contained in Follow(p,C)\mathrm{Follow}(p, C). By Lemma 1, M⊆M′M \subseteq M', and therefore

Fol(p,A)=⋃FIRST(γ M(p,B→β⋅Aγ))⊆⋃FIRST(γ M′(p,B→β⋅Aγ))⊆Follow(p,A),\mathrm{Fol}(p, A) = \bigcup \mathrm{FIRST}(\gamma\, M(p, B \to \beta \cdot A \gamma)) \subseteq \bigcup \mathrm{FIRST}(\gamma\, M'(p, B \to \beta \cdot A \gamma)) \subseteq \mathrm{Follow}(p, A),

the last step by the same computation as in the first paragraph with M′M' and Follow in place of MM and Fol. □\square

Theorem 5. Line L7 sets LA(q,A→ω)=M(q,A→ω⋅)\mathrm{LA}(q, A \to \omega) = M(q, A \to \omega \cdot) for every completed item with A≠S′A \ne S'.

Proof. Line L7 takes, for each transition (p,A)(p, A) and production A→ωA \to \omega, the state q=GOTO(p,ω)q = \mathrm{GOTO}(p, \omega), which is defined because A→⋅ω∈p‾A \to \cdot \omega \in \overline{p}, and adds Follow(p,A)\mathrm{Follow}(p, A). So it computes the union of Follow over the lookback pairs, which by Lemma 4 and (2) is M(q,A→ω⋅)M(q, A \to \omega \cdot). Every completed item gets a set, because by (1) it has at least one lookback pair. □\square

Part 4: DIGRAPH

Lemma 6. DIGRAPH(X,R,F′)(X, R, F') returns F(x)=Reach(x)F(x) = \mathrm{Reach}(x) for every xx.

Proof. The search is Tarjan's strongly connected components algorithm, with N(x)N(x) in the role of the low link and N=∞N = \infty marking finished nodes, so that line L11 does not lower N(x)N(x) through them. Tarjan's analysis gives three facts for it: when line L12 finds N(x)=dN(x) = d, the nodes popped are exactly the strongly connected component of xx; every node of that component was first visited inside the call on xx; and every component reachable from it by an edge leaving it was finished earlier.

Every set ever stored in F(u)F(u) is contained in Reach(u)\mathrm{Reach}(u): it starts as F′(u)F'(u) and grows only by F(v)F(v) for an edge uRvu R v, and Reach(v)⊆Reach(u)\mathrm{Reach}(v) \subseteq \mathrm{Reach}(u); the sets copied at line L12 go to nodes of one component, which all have the same Reach.

We show by induction on the order in which components finish that, when the component QQ with root xx finishes, F(x)⊇Reach(x)F(x) \supseteq \mathrm{Reach}(x). Each u∈Qu \in Q is visited inside the call on xx, and when the call on a node returns, line L11 adds its set to its caller's set, so F(x)⊇F(u)⊇F′(u)F(x) \supseteq F(u) \supseteq F'(u) for the value of F(u)F(u) when its call returned. During that call, line L11 was run for every edge uRvu R v, after the call on vv if vv was new; if vv lies in a component other than QQ, that component finished earlier and F(v)=Reach(v)F(v) = \mathrm{Reach}(v) by induction. So F(x)F(x) contains F′(u)F'(u) for every u∈Qu \in Q and Reach(v)\mathrm{Reach}(v) for every edge from QQ to another component, and these together make up Reach(x)\mathrm{Reach}(x). With the previous paragraph, F(x)=Reach(x)F(x) = \mathrm{Reach}(x), and line L12 gives every member of QQ this set, which is its own Reach. Later steps never change the set of a finished node. □\square

The implementation replaces the recursion by an explicit stack of frames (x,d,i)(x, d, i), where ii is the position of the next successor of xx to look at. When a frame is removed, the update of line L11 for the edge from its caller is done at once, so the order of operations is the same as in the recursive version.

Conclusion. By Lemma 6, lines L4 and L6 compute the least solutions Read and Follow; by Theorem 5, line L7 gives each completed item exactly its lookaheads in the canonical LR(1) states with the same core, which are the LALR(1) lookaheads. ∎

Back to LALR lookahead computation