Algorithm Search⌘K

Proofs: Generalized LR parsing

These are the human proofs of Generalized LR parsing, at full length.

GLR accepts exactly the words of the grammar and returns a parse tree full

This proof shows: correctness.

Notation. G=(V,Σ,P,S)G = (V, \Sigma, P, S) is any context-free grammar, augmented with a new start symbol S′S' and the production S′→SS' \to S, and w=a1⋯anw = a_1 \cdots a_n. For 0≤i≤j≤n0 \le i \le j \le n, write wi,j=ai+1⋯ajw_{i,j} = a_{i+1} \cdots a_j. Items, CLOSURE, GOTO, the states QQ and q0q_0 are as on the page. For a string γ=X1⋯Xk\gamma = X_1 \cdots X_k, δ(q,γ)=GOTO(⋯GOTO(q,X1)⋯ ,Xk)\delta(q, \gamma) = \mathrm{GOTO}(\cdots \mathrm{GOTO}(q, X_1) \cdots, X_k) when every step is defined, and δ(q,ε)=q\delta(q, \varepsilon) = q. A node vv of the GSS has a state state(v)\mathrm{state}(v) and a level level(v)\mathrm{level}(v). A path of mm edges from uu is a sequence u=y0,y1,…,ymu = y_0, y_1, \ldots, y_m with an edge yr−1→yry_{r-1} \to y_r for each rr; nodes may repeat.

Facts about the LR(0) automaton

Fact 1 (dot positions). CLOSURE adds only items with the dot at the start. So every item with the dot after the start in GOTO(q,X)\mathrm{GOTO}(q, X) has the form A→βX∙γA \to \beta X \bullet \gamma, with A→β∙Xγ∈qA \to \beta \bullet X \gamma \in q. Such an item exists, since GOTO is defined only for a nonempty kernel. Hence every state s=GOTO(q,X)s = \mathrm{GOTO}(q, X) determines XX, its accessing symbol X(s)X(s), and q0q_0, which has no item with the dot after the start, is never a value of GOTO.

Fact 2 (items move back to the start). If A→β1∙β2∈δ(t,γ)A \to \beta_1 \bullet \beta_2 \in \delta(t, \gamma) and ∣γ∣=∣β1∣|\gamma| = |\beta_1|, then γ=β1\gamma = \beta_1 and A→∙β1β2∈tA \to \bullet \beta_1 \beta_2 \in t. In particular, if A→α∙∈δ(t,γ)A \to \alpha \bullet \in \delta(t, \gamma) and ∣γ∣=∣α∣|\gamma| = |\alpha|, then γ=α\gamma = \alpha and A→∙α∈tA \to \bullet \alpha \in t.

Proof. By induction on d=∣β1∣d = |\beta_1|. For d=0d = 0, γ=ε\gamma = \varepsilon and δ(t,γ)=t\delta(t, \gamma) = t. For d>0d > 0, write γ=γ′X\gamma = \gamma' X. The item has the dot after the start and is in GOTO(δ(t,γ′),X)\mathrm{GOTO}(\delta(t, \gamma'), X), so by Fact 1, β1=β1′X\beta_1 = \beta_1' X and A→β1′∙Xβ2∈δ(t,γ′)A \to \beta_1' \bullet X \beta_2 \in \delta(t, \gamma'), with ∣γ′∣=∣β1′∣|\gamma'| = |\beta_1'|. By induction, γ′=β1′\gamma' = \beta_1' and A→∙β1′Xβ2∈tA \to \bullet \beta_1' X \beta_2 \in t. So γ=β1\gamma = \beta_1. □\square

Fact 3 (valid items are present). If S′⇒rm∗δAz⇒rmδβ1β2zS' \Rightarrow^*_{rm} \delta A z \Rightarrow_{rm} \delta \beta_1 \beta_2 z is a rightmost derivation, then δ(q0,δβ1)\delta(q_0, \delta \beta_1) is defined and contains A→β1∙β2A \to \beta_1 \bullet \beta_2.

Proof. By the definition of GOTO, if B→η1∙Xη2∈qB \to \eta_1 \bullet X \eta_2 \in q, then GOTO(q,X)\mathrm{GOTO}(q, X) is defined and contains B→η1X∙η2B \to \eta_1 X \bullet \eta_2. Applying this ∣β1∣|\beta_1| times, it suffices to show A→∙β1β2∈δ(q0,δ)A \to \bullet \beta_1 \beta_2 \in \delta(q_0, \delta). We use induction on the length of the derivation S′⇒rm∗δAzS' \Rightarrow^*_{rm} \delta A z. If it has zero steps, then A=S′A = S', δ=ε\delta = \varepsilon, and S′→∙S∈q0S' \to \bullet S \in q_0. Otherwise, consider the step that introduced this occurrence of AA: S′⇒rm∗δ′Bz′⇒rmδ′η1Aη2z′⇒rm∗δAzS' \Rightarrow^*_{rm} \delta' B z' \Rightarrow_{rm} \delta' \eta_1 A \eta_2 z' \Rightarrow^*_{rm} \delta A z. In a rightmost derivation, no symbol to the left of a nonterminal that is not yet rewritten is ever rewritten, so the steps after the introduction rewrite only η2\eta_2, and δ=δ′η1\delta = \delta' \eta_1. The derivation of δ′Bz′\delta' B z' is shorter, so by induction B→∙η1Aη2∈δ(q0,δ′)B \to \bullet \eta_1 A \eta_2 \in \delta(q_0, \delta'). Moving the dot over η1\eta_1 gives B→η1∙Aη2∈δ(q0,δ)B \to \eta_1 \bullet A \eta_2 \in \delta(q_0, \delta), and the closure then contains A→∙β1β2A \to \bullet \beta_1 \beta_2. □\square

Soundness

Lemma 1. For every edge v→xv \to x with v=(s,j)v = (s, j) and x=(t,i)x = (t, i): i≤ji \le j, s=GOTO(t,X(s))s = \mathrm{GOTO}(t, X(s)), and the tree on the edge is a parse tree of X(s)X(s) with yield wi,jw_{i,j} (for a terminal, the leaf itself).

Proof. By induction on the order in which edges are made. A shift edge (line L12) goes from (s,j+1)(s, j + 1) to u∈Uju \in U_j, with s=GOTO(state(u),aj+1)s = \mathrm{GOTO}(\mathrm{state}(u), a_{j+1}). By Fact 1, X(s)=aj+1X(s) = a_{j+1}, and its leaf has yield wj,j+1w_{j,j+1}.

A reduction edge (line L10) comes from an entry (u,A→α,e)(u, A \to \alpha, e) with u∈Uju \in U_j and A→α∙∈state(u)A \to \alpha \bullet \in \mathrm{state}(u), and from a path u=y0,…,ym=xu = y_0, \ldots, y_m = x with m=∣α∣m = |\alpha|, all of whose edges were made earlier. By induction, state(yr−1)=GOTO(state(yr),Xr)\mathrm{state}(y_{r-1}) = \mathrm{GOTO}(\mathrm{state}(y_r), X_r) with Xr=X(state(yr−1))X_r = X(\mathrm{state}(y_{r-1})), and level(yr)≤level(yr−1)\mathrm{level}(y_r) \le \mathrm{level}(y_{r-1}). So state(u)=δ(state(x),γ)\mathrm{state}(u) = \delta(\mathrm{state}(x), \gamma) with γ=Xm⋯X1\gamma = X_m \cdots X_1, and by Fact 2, γ=α\gamma = \alpha and A→∙α∈state(x)A \to \bullet \alpha \in \mathrm{state}(x). Hence s=GOTO(state(x),A)s = \mathrm{GOTO}(\mathrm{state}(x), A) is defined, and X(s)=AX(s) = A by Fact 1. The levels give i=level(x)≤level(u)=ji = \mathrm{level}(x) \le \mathrm{level}(u) = j. The trees on the edges ym−1→ym,…,y0→y1y_{m-1} \to y_m, \ldots, y_0 \to y_1 are parse trees of Xm,…,X1X_m, \ldots, X_1 with yields wlevel(ym),level(ym−1),…,wlevel(y1),level(y0)w_{\mathrm{level}(y_m), \mathrm{level}(y_{m-1})}, \ldots, w_{\mathrm{level}(y_1), \mathrm{level}(y_0)}, which concatenate to wi,jw_{i,j}. With these children, bottom first, in the order of α\alpha, the new tree is a parse tree of AA with yield wi,jw_{i,j}. □\square

Corollary. If line L13 returns true, then the edge from (GOTO(q0,S),n)(\mathrm{GOTO}(q_0, S), n) to the root carries a parse tree of X(GOTO(q0,S))=SX(\mathrm{GOTO}(q_0, S)) = S with yield w0,n=ww_{0,n} = w, so S⇒∗wS \Rightarrow^* w.

Termination

Each level has at most ∣Q∣|Q| nodes, and the levels are 0,…,n0, \ldots, n, so there are finitely many nodes and edges. In phase jj, line L4 queues finitely many entries, line L8 queues entries only when it makes a node, and line L9 only when it makes an edge. So finitely many entries are queued. For each entry, line L7 enumerates finitely many paths, since they have ∣α∣|\alpha| edges and each node has finitely many out-edges; the set of paths is fixed when the entry is removed. So every phase ends.

Completeness

Edges are made only in two places. Line L10 in phase jj makes edges whose source is at level jj; line L12 in phase jj makes edges whose source is at level j+1j + 1. A path from a node of level jj never goes up a level (Lemma 1), so it uses only edges with a source at level at most jj. Hence after the loop of lines L5 to L10 in phase jj ends, no edge on a path from a node of level jj is ever made again, and UjU_j never changes again.

Lemma 2 (saturation). When the loop of lines L5 to L10 of phase jj ends, the following holds. For every u∈Uju \in U_j, every A→α∈R(state(u))A \to \alpha \in R(\mathrm{state}(u)), and every path PP of m=∣α∣m = |\alpha| edges from uu to a node xx, the node v=(GOTO(state(x),A),j)v = (\mathrm{GOTO}(\mathrm{state}(x), A), j) exists and has the edge v→xv \to x.

Proof. It suffices to show that some entry (u,A→α,e)(u, A \to \alpha, e) is removed at line L6 after all edges of PP exist, with ee none or an edge of PP. Then line L7 enumerates PP, and lines L8 and L10 make vv and the edge if they are missing. (GOTO is defined here by the proof of Lemma 1, which shows A→∙α∈state(x)A \to \bullet \alpha \in \mathrm{state}(x).) The phase ends only when the queue is empty, so every queued entry is removed.

If m=0m = 0, then PP has no edges and x=ux = u. The node uu is in UjU_j either at the start of the phase, and then line L4 queues (u,A→α,none)(u, A \to \alpha, \text{none}), or it is made by line L8, which queues the same entry. Now let m≥1m \ge 1, and let ff be the edge of PP that was made last.

Case (a): ff existed before the loop of phase jj began. Then all edges of PP existed, so did their sources, and u∈Uju \in U_j at line L4, which queued (u,A→α,none)(u, A \to \alpha, \text{none}).

Case (b): ff was made in the loop, at line L10, in the same step in which line L8 made its source v′v'. Let frf_r be the first occurrence of ff in PP. If r>1r > 1, the edge fr−1f_{r-1} ends at v′v' and is different from ff, because ff ends at a node that existed before v′v', while fr−1f_{r-1} ends at v′v'. So fr−1f_{r-1} was made before ff, but after v′v' was made, and nothing is made between line L8 and line L10 of one step. This is impossible, so r=1r = 1 and u=v′u = v'. When line L8 made uu, it queued (u,A→α,none)(u, A \to \alpha, \text{none}), which is removed after this step, when all edges of PP exist.

Case (c): ff was made in the loop, at line L10, from a source v′v' that already existed. Then the edge was new, and line L9 of the same step queued (u′,r,f)(u', r, f) for every u′∈Uju' \in U_j and every r∈R(state(u′))r \in R(\mathrm{state}(u')) with a nonempty right side. The node uu was in UjU_j at that time: it is v′v' if ff is the first edge of PP, and otherwise it is the source of the first edge of PP, which was made before ff. Since m≥1m \ge 1, the entry (u,A→α,f)(u, A \to \alpha, f) was queued, and it is removed after ff is made, when all edges of PP exist. The path PP uses ff. □\square

Lemma 3 (the stacks of a rightmost derivation). Let S=φ0⇒rmφ1⇒rm⋯⇒rmφt=wS = \varphi_0 \Rightarrow_{rm} \varphi_1 \Rightarrow_{rm} \cdots \Rightarrow_{rm} \varphi_t = w, with t≥1t \ge 1, where step kk rewrites φk=δkAkzk\varphi_k = \delta_k A_k z_k (zk∈Σ∗z_k \in \Sigma^*) by Ak→αkA_k \to \alpha_k. Consider the sequence of configurations (γ,i)(\gamma, i) of a shift-reduce parser that starts at (ε,0)(\varepsilon, 0) and, for k=t−1k = t - 1 down to 00, shifts input symbols until (γ,i)=(δkαk,n−∣zk∣)(\gamma, i) = (\delta_k \alpha_k, n - |z_k|), then reduces to (δkAk,n−∣zk∣)(\delta_k A_k, n - |z_k|). Then this sequence is well defined, ends at (S,n)(S, n), and γ ai+1⋯an\gamma\, a_{i+1} \cdots a_n is a right sentential form for each configuration. Also, δ(q0,γ)\delta(q_0, \gamma) is defined for every γ\gamma in it.

Proof. We show by downward induction on kk that before the shifts for step kk, the configuration (γ,i)(\gamma, i) has γai+1⋯an=φk+1\gamma a_{i+1} \cdots a_n = \varphi_{k+1} and γ\gamma a prefix of δkαk\delta_k \alpha_k. Then shifting brings the stack to δkαk\delta_k \alpha_k, since φk+1=δkαkzk\varphi_{k+1} = \delta_k \alpha_k z_k, and the reduction gives δkAk\delta_k A_k with δkAkzk=φk\delta_k A_k z_k = \varphi_k. For k=t−1k = t - 1, the configuration is (ε,0)(\varepsilon, 0) and φt=w\varphi_t = w. For the step from kk to k−1k - 1: φk=δk−1αk−1zk−1\varphi_k = \delta_{k-1} \alpha_{k-1} z_{k-1}, and AkA_k is the rightmost nonterminal of φk\varphi_k. Since zk−1z_{k-1} has no nonterminal, AkA_k lies in δk−1αk−1\delta_{k-1} \alpha_{k-1}, so δkAk\delta_k A_k is a prefix of δk−1αk−1\delta_{k-1} \alpha_{k-1}. At the end, φ0=S\varphi_0 = S gives δ0=ε\delta_0 = \varepsilon, A0=SA_0 = S, z0=εz_0 = \varepsilon, and the configuration (S,n)(S, n).

Each stack γ\gamma of the sequence is SS or a prefix of some δkαk\delta_k \alpha_k. The derivation S′⇒rmS⇒rm∗δkAkzk⇒rmδkαkzkS' \Rightarrow_{rm} S \Rightarrow^*_{rm} \delta_k A_k z_k \Rightarrow_{rm} \delta_k \alpha_k z_k and Fact 3 show that δ(q0,δkαk)\delta(q_0, \delta_k \alpha_k) is defined, so it is defined on all prefixes. Also GOTO(q0,S)\mathrm{GOTO}(q_0, S) is defined, since S′→∙S∈q0S' \to \bullet S \in q_0. □\square

For a configuration (X1⋯Xk,i)(X_1 \cdots X_k, i) of this sequence, let lrl_r be the input position of the configuration just after XrX_r was pushed, so l1≤⋯≤lk≤il_1 \le \cdots \le l_k \le i, and let l0=0l_0 = 0. We say the configuration is in the GSS if, for vr=(δ(q0,X1⋯Xr),lr)v_r = (\delta(q_0, X_1 \cdots X_r), l_r), the nodes v0,…,vkv_0, \ldots, v_k and the edges vr→vr−1v_r \to v_{r-1} exist for 1≤r≤k1 \le r \le k, where v0v_0 is the root.

Lemma 4. Every configuration (γ,i)(\gamma, i) of the sequence of Lemma 3 is in the GSS, with all its nodes and edges made by the end of the loop of lines L5 to L10 of phase ii.

Proof. By induction along the sequence. The first configuration (ε,0)(\varepsilon, 0) is the root, made at line L2. Note that every node of γ\gamma at level ii and every edge with a source at level ii is made in phase i−1i - 1 at line L12 or in phase ii at line L10, so it already exists at the end of that loop if it exists at all.

Shift from (γ,i)(\gamma, i) to (γai+1,i+1)(\gamma a_{i+1}, i + 1). By induction, the top node u=(δ(q0,γ),i)u = (\delta(q_0, \gamma), i) is in UiU_i when line L11 of phase ii runs. The state s=GOTO(state(u),ai+1)=δ(q0,γai+1)s = \mathrm{GOTO}(\mathrm{state}(u), a_{i+1}) = \delta(q_0, \gamma a_{i+1}) is defined by Lemma 3, so line L12 makes the node (s,i+1)(s, i + 1) and the edge to uu. This happens before phase i+1i + 1 starts.

Reduction from (δα,i)(\delta \alpha, i) to (δA,i)(\delta A, i) by A→αA \to \alpha, with m=∣α∣m = |\alpha|. By induction, the path v0,…,v∣δ∣+mv_0, \ldots, v_{|\delta| + m} exists at the end of the loop of phase ii, and its top node uu has level ii. The last mm edges of it form a path of mm edges from uu to x=v∣δ∣=(δ(q0,δ),l∣δ∣)x = v_{|\delta|} = (\delta(q_0, \delta), l_{|\delta|}). The item A→α∙A \to \alpha \bullet is valid for δα\delta \alpha (Lemma 3 with Fact 3), so it is in state(u)=δ(q0,δα)\mathrm{state}(u) = \delta(q_0, \delta \alpha), and A→α∈R(state(u))A \to \alpha \in R(\mathrm{state}(u)). By Lemma 2, the node (GOTO(state(x),A),i)=(δ(q0,δA),i)(\mathrm{GOTO}(\mathrm{state}(x), A), i) = (\delta(q_0, \delta A), i) exists, with an edge to xx. The symbol AA was pushed at position ii, so this is the node v∣δ∣+1v_{|\delta| + 1} of the new configuration, and the nodes below it are unchanged. □\square

Theorem. GLR terminates, returns true if and only if S⇒∗wS \Rightarrow^* w, and when it returns true, the tree it returns is a parse tree of ww from SS.

Proof. Termination is shown above. If GLR returns true, then S⇒∗wS \Rightarrow^* w and the tree is a parse tree, by the Corollary of Lemma 1. Conversely, if S⇒∗wS \Rightarrow^* w, then since ww has no nonterminal, there is a rightmost derivation with t≥1t \ge 1 steps. By Lemma 3 its last configuration is (S,n)(S, n), and by Lemma 4 the node (δ(q0,S),n)=(GOTO(q0,S),n)(\delta(q_0, S), n) = (\mathrm{GOTO}(q_0, S), n) exists with an edge to the root. Line L13 runs after phase nn, so it finds them and returns true. ■\blacksquare

Back to Generalized LR parsing