The LL(k) tables are conflict-free exactly for LL(k) grammars, and LLK-PARSE accepts exactly the sentences in linear time with exact error positions full
This proof shows: correctness.
Statement. Let G=(V,Σ,R,S) be a grammar in which every nonterminal derives some terminal string, and let k≥1. Then:
- LLK-TABLES reports a conflict if and only if G is not LL(k);
- if it reports none, then for every input w=a1⋯an, LLK-PARSE stops after at most c⋅(n+1) steps, where c depends only on G and k;
- it accepts if and only if w∈L(G), and then it returns a parse tree of w with root S;
- if it reports an error at position p (with p=n+1 meaning the end of the input), then a1⋯ap−1 is a prefix of a sentence, and a1⋯ap is not when p≤n.
Setup. For α∈(V∪Σ)∗ write L(α) for the set of terminal strings that α derives; by the hypothesis, L(α)=∅ for every α. The sets computed at line L12 are the least fixed point of FA=⋃A→Y1⋯YmFY1⊕k⋯⊕kFYm, with Fa={a} for a terminal. They equal FIRSTk(A). Each element of the fixed point is FIRSTk of a derived string, by induction on the iteration. Conversely, by induction on the height of a parse tree with root A and yield x, FIRSTk(x) enters the fixed point, since FIRSTk(x1⋯xm) depends only on the FIRSTk(xj). The operation ⊕k is associative, and FIRSTk(αβ)=FIRSTk(α)⊕kFIRSTk(β). So the set U of line L15 is FIRSTk(Y1⋯Ym)⊕kL, and the set Lj of line L17 is FIRSTk(Yj+1⋯Ym)⊕kL. Every U is nonempty because every symbol is productive.
Step 1: every table comes from a left-sentential form. Claim: for every table T(A,L) that LLK-TABLES creates, there is a leftmost derivation S⇒lm∗uAα with u∈Σ∗ and FIRSTk(α)=L. For T(S,{ε}) take u=α=ε. If T(Yj,Lj) is created while T(A,L) is filled, with the production A→Y1⋯Ym and a form uAα for T(A,L), then
uAα⇒lmuY1⋯Ymα⇒lm∗uz1⋯zj−1YjYj+1⋯Ymα, where each Yi with i<j is derived to some zi∈L(Yi), leftmost. The context is α′=Yj+1⋯Ymα, and FIRSTk(α′)=FIRSTk(Yj+1⋯Ym)⊕kL=Lj.
Step 2: the stack invariant. Read the stack from the top as (X1,t1),…,(Xq,tq). Claim: at each test of line L2, whenever Xj∈V, its table is tj=T(Xj,FIRSTk(Xj+1⋯Xq)). Moreover, if i−1 tokens have been matched, the tree built so far is the tree of a leftmost derivation S⇒lm∗a1⋯ai−1X1⋯Xq, with one slot for each stack entry.
At the start the stack is (S,T(S,{ε})). A match removes the top terminal; the matched prefix grows by it, and the other entries keep their tables and the symbols below them. Now take an expansion of (X1,T(X1,L)) with L=FIRSTk(X2⋯Xq), by X1→Y1⋯Ym. It pushes Yj with the table T(Yj,Lj), where
Lj=FIRSTk(Yj+1⋯Ym)⊕kFIRSTk(X2⋯Xq)=FIRSTk(Yj+1⋯YmX2⋯Xq). That is the claim for the new stack. The step rewrites the leftmost nonterminal of a1⋯ai−1X1⋯Xq, so it is a leftmost step.
A consequence: when X1∈V is on top with the table T(X1,L), the keys of the table are the union over the productions X1→β of FIRSTk(β)⊕kL, which is FIRSTk(X1⋯Xq).
Step 3: acceptance gives a parse tree. The parser accepts only when the stack is empty and i=n+1. By Step 2 the tree is then the tree of a derivation S⇒lm∗a1⋯an, so it is a parse tree of w, and w∈L(G).
Step 4: sentences are accepted. Assume no conflict, let w∈L(G), and fix a parse tree t of w. As in the LL(1) case, the claim is that the parser expands the nodes of t in preorder with their productions in t. Suppose that so far it has done so, and that the top slot is the node x of t, with i−1 tokens matched. The stack then holds the slots of t that come after the matched leaves, in preorder of the remaining frontier. If x is a terminal leaf, it is ai and the parser matches it. If x is labeled X1∈V and uses X1→β in t, the subtrees of the stack slots spell ai⋯an. So ai⋯an∈L(βX2⋯Xq), and u=FIRSTk(ai⋯an), the lookahead of line L7, lies in FIRSTk(β)⊕kL with L=FIRSTk(X2⋯Xq) by Step 2. Line L18 then put X1→β into T(X1,L)[u]. Since there is no conflict, it is the only production there, and the parser expands x as t does. When all nodes of t are processed, the stack is empty, i=n+1, and the parser accepts.
Step 5: conflicts are exactly the violations of LL(k). Suppose LLK-TABLES reports a conflict in T(A,L), between productions A→β and A→γ that share a lookahead u. Take the form u0Aα of Step 1, with FIRSTk(α)=L. Then u∈FIRSTk(βα)∩FIRSTk(γα), so there are x∈L(βα) and y∈L(γα) with FIRSTk(x)=FIRSTk(y)=u, and G is not LL(k).
Conversely, suppose there is no conflict but G is not LL(k). Take two leftmost derivations S⇒lm∗u0Aα⇒lmu0βα⇒lm∗u0x and S⇒lm∗u0Aα⇒lmu0γα⇒lm∗u0y with β=γ and FIRSTk(x)=FIRSTk(y)=u. Run the parser on u0x∈L(G). By Step 4 it follows the tree of the first derivation in preorder, so at some point it has matched u0 and has A on top, with the stack Aα and the table T(A,FIRSTk(α)) by Step 2. Both FIRSTk(βα) and FIRSTk(γα) contain u, so line L16 saw a conflict in this table, a contradiction. This proves part 1.
Step 6: no left recursion. Assume no conflict, so that G is LL(k) by Step 5. Claim: no nonterminal A that is reachable from S has a derivation A⇒+βAδ with β⇒∗ε.
Suppose one does. Along the path to the inner A we get nonterminals A0=A,A1,…,Ar=A, with r≥1, and productions pj=Aj→βjAj+1δj with βj⇒∗ε, indices modulo r. Each Aj is reachable from S, because A is and A⇒∗⋯Aj⋯. Among all complete trees whose root is one of the Aj, choose one of least height, with root Aj, root production q and yield x. Then q=pj, since otherwise its child Aj+1 would root a lower complete tree.
Going once around the cycle from Aj with pj first, and deriving each β to ε before the next step, gives Aj⇒lm+Ajζ for a string ζ. Pick z∈L(ζ), nonempty if possible. Since Aj is reachable and every symbol is productive, some leftmost derivation reaches u0Ajα with u0∈Σ∗; let y∈L(α). For any m≥0, S⇒lm∗u0Ajζmα, and from this form:
- applying q first gives u0xzmy;
- applying pj first gives u0Ajζm+1α⇒∗u0xzm+1y.
If z=ε, take m=k; then both strings after u0 start with xzk, which has length at least k. If z=ε, both strings are u0xy. Either way the first k tokens after u0 agree while the productions q and pj differ, against the LL(k) condition.
Step 7: the tree is small, and the parser stops. Steps 5 and 6 of the proof for LL(1) parsing use only the absence of the left recursion of Step 6, and they apply word for word. When m tokens have been matched, every downward path between inner nodes with the same start index has distinct labels, because all labels in the tree are reachable from S. So the partial tree has at most c0(m+1) inner nodes, with c0=(2∣V∣+1)(1+r0∣V∣+1) and r0≥2 at least the length of every right side. Each step is a match (at most n), an expansion (one new inner node) or the last step, so there are at most c⋅(n+1) steps with c=c0+2. This is part 2. If w∈/L(G), the parser stops and cannot accept by Step 3, so it reports an error. With Step 4 this is part 3.
Step 8: the inspected tokens stay consistent. Let h be the end of the furthest lookahead used so far: the largest min(i′+k−1,n) over the expansions done so far at positions i′, or 0 if there were none. Claim: at each test of line L2, with stack γ=X1⋯Xq and i−1 tokens matched, h≤i+k−1, and ai⋯ah is a prefix of some element of FIRSTk(γ) (the empty string when h<i).
The bound on h holds because the positions i′ never exceed i. After an expansion at i with the lookahead u=ai⋯amin(i+k−1,n), we have h=min(i+k−1,n). The new stack βX2⋯Xq was chosen with u∈FIRSTk(β)⊕kFIRSTk(X2⋯Xq), which is FIRSTk of the new stack. After a match of X1=ai, let ai⋯ah be a prefix of v=FIRSTk(aiz) with z∈L(X2⋯Xq). Then ai+1⋯ah is a prefix of FIRSTk−1(z), which is a prefix of FIRSTk(z)∈FIRSTk(X2⋯Xq). Since every γ is productive, FIRSTk(γ) is never empty, which covers h<i.
Step 9: the valid prefix property. Suppose the parser reports an error at position p, in configuration (i,γ). Every element v∈FIRSTk(γ) is FIRSTk(z) for some z∈L(γ), and a1⋯ai−1z∈L(G) by Step 2. We now check the three places where an error can be reported.
- Line L5. Here p=i and γ starts with the terminal X1. The prefix a1⋯ai−1 extends to a sentence.
- Line L8. Here p=i+d, where u and some key v∈FIRSTk(γ) share d tokens. The prefix a1⋯ap−1 is a1⋯ai−1 followed by the first d tokens of v, so it starts a sentence. By Step 8, ai⋯ah is a prefix of a key, so d≥h−i+1 and p>h.
- Line L11. Here γ=ε and p=i; then a1⋯ai−1∈L(G). If the last decision ended at h≥i, Step 8 with γ=ε gives ai⋯ah=ε, so h<i=p.
In all three cases p>h, because at line L5 we have h≤i−1: if h≥i, then ai is the first token of an element of FIRSTk(X1⋯), which starts with X1, so X1=ai and there is no error.
Now let p≤n and suppose some sentence s starts with a1⋯ap. Every expansion so far looked at tokens with positions at most h<p, and every match at positions below i≤p. The parser therefore makes the same moves on s as on w and reaches the same configuration (i,γ). On s it accepts by Step 4, and the rest of its run derives the rest of s from γ, so FIRSTk(sisi+1⋯)∈FIRSTk(γ). We look at the three lines again.
- Line L5. On s the parser matches X1=si=ai, a contradiction.
- Line L8. On s the lookahead is a key of t that agrees with u on its first d+1 tokens, because s and w agree up to position p=i+d. This contradicts the maximality of d.
- Line L11. The stack is empty while s has the token sp=ap left, so the parser would not accept s.
This proves part 4. ■