Algorithm Search⌘K

Proofs: LL parse table

These are the human proofs of LL parse table, at full length.

BUILD fills each cell with exactly the productions whose PREDICT set contains the token full

This proof shows: correctness.

Statement. Let G=(V,Σ,R,S)G = (V, \Sigma, R, S) be a grammar in which every nonterminal is reachable from SS. When BUILD(G)(G) stops, the computed sets equal Null\mathrm{Null}, FIRST(A)\mathrm{FIRST}(A) and FOLLOW(A)\mathrm{FOLLOW}(A) as defined on the page, for each A∈VA \in V, and each cell satisfies invariant (T): M[A,a]M[A, a] holds exactly the productions A→αA \to \alpha with a∈PREDICT(A→α)a \in \mathrm{PREDICT}(A \to \alpha). LOOKUP(M,A,a)(M, A, a) returns error exactly when no production of AA has aa in its PREDICT set, and the unique such production when there is one. Without the reachability hypothesis, Null\mathrm{Null} and FIRST are still exact, and the computed FOLLOW(A)\mathrm{FOLLOW}(A) contains the true one.

Setup. We treat $\$ as an extra terminal and work with sentential forms of S$S\$. For a string γ\gamma over V∪Σ∪{$}V \cup \Sigma \cup \{\$\}, FIRST(γ)={a:γ⇒∗aρ}\mathrm{FIRST}(\gamma) = \{ a : \gamma \Rightarrow^* a \rho \}. We use the splitting lemma of the derivation page in its general form, whose proof is the same: if Y1⋯Yk⇒mγY_1 \cdots Y_k \Rightarrow^m \gamma, then γ=γ1⋯γk\gamma = \gamma_1 \cdots \gamma_k with Yi⇒miγiY_i \Rightarrow^{m_i} \gamma_i and ∑mi=m\sum m_i = m. A consequence: a∈FIRST(Y1⋯Yk)a \in \mathrm{FIRST}(Y_1 \cdots Y_k) if and only if there is an ii with Y1⋯Yi−1⇒∗εY_1 \cdots Y_{i-1} \Rightarrow^* \varepsilon and a∈FIRST(Yi)a \in \mathrm{FIRST}(Y_i), since the first terminal of γ\gamma lies in the first nonempty piece γi\gamma_i. The computation of Null\mathrm{Null} is proved correct on the nullable symbol page. We write F(⋅)F(\cdot) and Fo(⋅)Fo(\cdot) for the sets that the loops compute.

Step 1: termination. Each loop of SETS repeats a pass only when the pass added an element to some set. The sets are subsets of the finite sets VV, V×ΣV \times \Sigma and V×(Σ∪{$})V \times (\Sigma \cup \{\$\}), and elements are never removed. So each loop makes at most ∣V∣(∣Σ∣+1)+1|V|(|\Sigma| + 1) + 1 passes, and BUILD stops.

Step 2: FIRST is sound. Claim: if aa is added to F(A)F(A), then a∈FIRST(A)a \in \mathrm{FIRST}(A). Induction on the order of the additions. The rule of lines L3 and L4 adds aa when A→X1⋯XkA \to X_1 \cdots X_k, X1⋯Xi−1X_1 \cdots X_{i-1} is nullable, and a∈F(Xi)a \in F(X_i), where F(a)={a}F(a) = \{a\} for a terminal. If XiX_i is a nonterminal, aa was added to F(Xi)F(X_i) earlier, so Xi⇒∗aρX_i \Rightarrow^* a \rho by the induction hypothesis. In both cases A⇒X1⋯Xk⇒∗Xi⋯Xk⇒∗aρXi+1⋯XkA \Rightarrow X_1 \cdots X_k \Rightarrow^* X_i \cdots X_k \Rightarrow^* a \rho X_{i+1} \cdots X_k.

Step 3: FIRST is complete. Claim: if A⇒maρA \Rightarrow^m a \rho, then a∈F(A)a \in F(A) when the loop stops. Strong induction on m≥1m \ge 1. The first step is A⇒X1⋯XkA \Rightarrow X_1 \cdots X_k, and X1⋯Xk⇒m−1aρX_1 \cdots X_k \Rightarrow^{m-1} a \rho. By the splitting lemma there is an ii with X1⋯Xi−1⇒∗εX_1 \cdots X_{i-1} \Rightarrow^* \varepsilon and Xi⇒miaρ′X_i \Rightarrow^{m_i} a \rho' with mi≤m−1m_i \le m - 1. If XiX_i is the terminal aa, the rule adds aa to F(A)F(A). Otherwise a∈F(Xi)a \in F(X_i) by the induction hypothesis, and the last pass of the loop changed nothing, so the rule for A→X1⋯XkA \to X_1 \cdots X_k and this ii found aa already in F(A)F(A). With Step 2, F(A)=FIRST(A)F(A) = \mathrm{FIRST}(A), and then the formula of the page gives FIRST(α)\mathrm{FIRST}(\alpha) for each string α\alpha by the consequence of the splitting lemma.

Step 4: FOLLOW is complete. Claim: if S$⇒mβAγS\$ \Rightarrow^m \beta A \gamma, then FIRST(γ)⊆Fo(A)\mathrm{FIRST}(\gamma) \subseteq Fo(A). Since a∈FOLLOW(A)a \in \mathrm{FOLLOW}(A) means S$⇒∗βAaγ′S \$ \Rightarrow^* \beta A a \gamma', and a∈FIRST(aγ′)a \in \mathrm{FIRST}(a\gamma'), this gives FOLLOW(A)⊆Fo(A)\mathrm{FOLLOW}(A) \subseteq Fo(A). Induction on mm.

  • m=0m = 0: the form is S$S\$, so A=SA = S and γ=$\gamma = \$, and line L6 puts $\$ in Fo(S)Fo(S).

  • m≥1m \ge 1: the last step rewrites C→ηC \to \eta in δ1Cδ2\delta_1 C \delta_2, giving δ1ηδ2=βAγ\delta_1 \eta \delta_2 = \beta A \gamma, and S$⇒m−1δ1Cδ2S\$ \Rightarrow^{m-1} \delta_1 C \delta_2. Three cases for the position of this occurrence of AA.

    • In δ2\delta_2: δ2=ρAγ\delta_2 = \rho A \gamma, and the same occurrence has the right context γ\gamma in δ1Cδ2\delta_1 C \delta_2. The induction hypothesis applies.
    • In δ1\delta_1: δ1=βAρ\delta_1 = \beta A \rho and γ=ρηδ2\gamma = \rho \eta \delta_2. In the earlier form the right context is ρCδ2\rho C \delta_2, and ρCδ2⇒ρηδ2\rho C \delta_2 \Rightarrow \rho \eta \delta_2, so FIRST(γ)⊆FIRST(ρCδ2)⊆Fo(A)\mathrm{FIRST}(\gamma) \subseteq \mathrm{FIRST}(\rho C \delta_2) \subseteq Fo(A) by the induction hypothesis.
    • In η\eta: η=η1Aη2\eta = \eta_1 A \eta_2 and γ=η2δ2\gamma = \eta_2 \delta_2. Let a∈FIRST(η2δ2)a \in \mathrm{FIRST}(\eta_2 \delta_2). By the splitting lemma, either a∈FIRST(η2)a \in \mathrm{FIRST}(\eta_2), and lines L7 and L8 put aa in Fo(A)Fo(A) for the production C→η1Aη2C \to \eta_1 A \eta_2; or η2\eta_2 is nullable and a∈FIRST(δ2)a \in \mathrm{FIRST}(\delta_2). In the second case a∈Fo(C)a \in Fo(C) by the induction hypothesis for the occurrence of CC in δ1Cδ2\delta_1 C \delta_2, and line L8 adds Fo(C)Fo(C) to Fo(A)Fo(A) because η2\eta_2 is nullable.

    In each case the last pass of the loop changed nothing, so the element is in Fo(A)Fo(A) when the loop stops.

Step 5: FOLLOW is sound when every nonterminal is reachable. Claim: each element added to Fo(A)Fo(A) is in FOLLOW(A)\mathrm{FOLLOW}(A). Induction on the order of the additions. Line L6 adds $\$ to Fo(S)Fo(S), and S$S\$ itself shows $∈FOLLOW(S)\$ \in \mathrm{FOLLOW}(S). Line L8 uses a production B→αAβB \to \alpha A \beta. Since BB is reachable, S$⇒∗ρBτS \$ \Rightarrow^* \rho B \tau for some ρ,τ\rho, \tau. If a∈FIRST(β)a \in \mathrm{FIRST}(\beta), then S$⇒∗ραAβτ⇒∗ραAaρ′τS\$ \Rightarrow^* \rho \alpha A \beta \tau \Rightarrow^* \rho \alpha A a \rho' \tau. If β\beta is nullable and bb was added earlier to Fo(B)Fo(B), then b∈FOLLOW(B)b \in \mathrm{FOLLOW}(B) by the induction hypothesis, so S$⇒∗ρ′Bbτ′S\$ \Rightarrow^* \rho' B b \tau', and ρ′Bbτ′⇒ρ′αAβbτ′⇒∗ρ′αAbτ′\rho' B b \tau' \Rightarrow \rho' \alpha A \beta b \tau' \Rightarrow^* \rho' \alpha A b \tau'. In both cases the token is in FOLLOW(A)\mathrm{FOLLOW}(A). (Without reachability this step fails: a production of an unreachable BB can add tokens to Fo(A)Fo(A). Step 4 does not use reachability.)

Step 6: the cells. Lines L3 to L6 add p=A→αp = A \to \alpha to M[A,a]M[A, a] exactly when a∈FIRST(α)a \in \mathrm{FIRST}(\alpha), or α\alpha is nullable and a∈FOLLOW(A)a \in \mathrm{FOLLOW}(A); by Steps 2 to 5 these are the true sets. That is the definition of a∈PREDICT(p)a \in \mathrm{PREDICT}(p), and no other line adds to a cell. So (T) holds. LOOKUP reads the cell at line L7 and returns error when it is empty (line L8), reports the conflict when it has two or more productions (line L9), and returns its only production otherwise (line L10).

So BUILD fills every cell as (T) says, and LOOKUP returns its content. ■\blacksquare

Back to LL parse table