Proofs: LALR(1) parsing
These are the human proofs of LALR(1) parsing, at full length.
The LALR(1) table is the LR(1) table merged by core, and its driver parses exactly L(G) full
This proof shows: correctness.
We use the pseudocode of the page. is augmented with production 0, , where occurs on no right side. We assume that every nonterminal derives some terminal string. Then is not empty for every , and for every and every terminal or end marker .
LR(1) facts we use. The canonical LR(1) collection has the start state and the transitions . We use two standard results of Knuth (1965), also in Section 4.7 of the Dragon book.
- (K1) Validity. if and only if there is a rightmost derivation with (where is read as when ).
- (K2) The canonical parser. If the canonical LR(1) table has no conflict, the LR(1) driver (lines L12 to L17 with the canonical table) accepts every and never meets an empty entry on it. It follows the rightmost derivation of backwards: for each right sentential form of that derivation, with and the handle ending at the end of , there is a moment at which its stack spells and the rest of the input is .
The core of a set of LR(1) items is the set of its LR(0) items.
Lemma 1 (cores). For every set of LR(1) items, . Hence , and every canonical LR(1) state reachable from by has as its core the closure of the LR(0) state reachable from state 0 by .
Proof. Both closures add for the same items ; the LR(1) closure adds it with the lookaheads , and this set is not empty by our assumption. So an induction on the number of closure steps shows that the two sides contain the same LR(0) items. The other two claims follow by induction on .
For an LR(0) state and an item in its closure, let for some canonical LR(1) state with . Write for the set CLOSURE1 of lines L5 and L8, computed from the final sets LA.
Lemma 2 (no extra lookaheads). At every moment, for every kernel item of . Hence implies .
Proof. Line L2 is correct because and the only state with the kernel item is state 0. Suppose the claim holds before line L6 adds to because of . The LR(1) closure has the property , because each closure step uses one item. Each item of line L5 lies in some canonical state with core , by the hypothesis, and is closed, so . So lies in such a . Then , whose core is by Lemma 1, so . The second claim follows by the same argument for .
Lemma 3 (no missing lookaheads). After line L7, every canonical LR(1) state with core satisfies . Hence .
Proof. By induction on the length of a shortest path from to . The kernel of is , and by line L2; is monotone, so . Let with by induction, where . Each kernel item of is with . When line L7 ends, a full pass has changed nothing, so the pass of line L6 for found already in , and by Lemma 1. So the kernel of is in the set given to CLOSURE1 for , and by monotonicity . The equality then follows from Lemma 2.
The loop of lines L3 to L7 ends, because each pass that does not end it adds at least one element to a set LA, and these sets are subsets of a finite set.
Corollary 4. For every state and terminal or end marker , the entry of lines L8 to L10 is the union of the entries of the canonical LR(1) table over the states with core , where a shift to is read as a shift to . In particular, if the LALR table has no conflict, neither has the canonical table, and is LR(1).
Proof. The canonical table puts shift on in when an item with is in , and reduce or accept on when a completed item with lookahead is in . By Lemmas 2 and 3, is the union of these , and lines L9 and L10 read the same items. Shift targets agree by Lemma 1. Two different actions in some would appear in .
From now on, line L11 has passed, so every entry has at most one action, and by Corollary 4 the grammar is LR(1). LR(1) grammars are unambiguous (Knuth 1965).
Lemma 5 (soundness). At every moment of the driver, let the stack hold the states , with symbols , where is the symbol on the transition into . Then , , and the value stack holds trees , where is a derivation tree with root , and the leaves of in order spell the consumed input . If the driver returns a tree at line L16, it is a parse tree of .
Proof. Line L12 makes the claim true. Line L14 pushes with the leaf . At line L15, the reduction by is in because the completed item is in the closure of . In the LR(0) automaton, an item in the closure of with is a kernel item that came from in the closure of with . So, going down the stack, the top symbols are , and there are at least of them above . The new tree has root , its children are the popped trees in order, and it uses the production ; the leaves keep their order. The new state is of the exposed state on , which exists because the exposed state has in its closure and so an item with in its closure.
At line L16 the closure of contains and the lookahead is , so all of is consumed. The item comes only from , which is only in state 0, because is on no right side. No transition enters state 0, because every non-start kernel item has its dot after position 0. So the stack is with , and is a parse tree of .
Lemma 6 (completeness). If , the driver accepts .
Proof. Run the canonical LR(1) driver on next to the LALR driver. We show by induction on the number of moves that, before each move, the LALR stack is when the LR(1) stack is , and both have read the same input. This holds at the start. By (K2) the LR(1) driver has an action in . By Corollary 4, (with shift targets mapped to their cores) is in , which has no other action, so the LALR driver makes the same move. A shift pushes by Lemma 1. A reduction pops the same number of states from both stacks and pushes and , which correspond by Lemma 1. By (K2) the LR(1) driver accepts, so the LALR driver accepts at the same move.
Lemma 7 (termination). The driver stops on every input.
Proof. There are at most shifts, so it is enough to show that no run of reductions without a shift is infinite. Suppose that one is, with lookahead from time on. Each reduction pops the top entries and then pushes one; call the stack length after the pops the low point of the move. Let be the least low point of the moves at or after . It never decreases.
Claim T. Let and let be the top entry at time . Within a bounded number of moves, the driver pops . Let be its state. The driver makes a reduction at time , so some completed item in the closure of has by Lemma 2: there is a canonical state with core that contains . Let be reached by . By (K1), . Each nonterminal derives a terminal string, so derives a sentence with , through a rightmost derivation in which occurs. The canonical driver on follows this rightmost derivation backwards, so at some moment its stack spells with top state and lookahead . From that moment, compare it with the LALR driver from time , restricted to the entries above and above . As in Lemma 6, by (K2) and Corollary 4 the two drivers make the same moves, with the LALR states the cores of the LR(1) states, until one of them pops its base entry ( or ), and then the other pops its base entry at the same move, or until the LR(1) driver shifts , and then the LALR driver shifts . The LR(1) driver accepts in finitely many moves, so one of these events happens within a bound that does not depend on . A shift is excluded, so is popped.
Case 1: grows without bound. Let , and let be the last move at or after with low point ; it exists because some move has low point and from some time on. Every later move has a low point above , so the entry at position , which the move at pushed, is never popped. It is the top entry right after , and this contradicts Claim T.
Case 2: from some time on. The entries at positions are never popped after , and infinitely many moves have low point and push an entry at position . Each such entry has the symbol of the nonterminal it reduces to, so two of these moves, at times , push trees and with the same root . The consumed input does not change, so the trees above position span the same input before and after. Trees are never destroyed: a popped tree becomes a child of the new tree. Between and no move has a low point below , so stays inside some tree above position , and the move at pops all of these trees into . So is a subtree of . , and both span the same input. So with . Since derives a terminal string and occurs in a sentential form (it is the root of a tree in a viable stack, by Lemma 5 and Lemma 1), repeating this derivation gives infinitely many parse trees for one sentence, so is ambiguous. This contradicts the remark after Corollary 4.
Theorem. If line L11 finds no conflict, LALR-PARSE returns a parse tree of if and "reject" otherwise. If it finds a conflict, has no conflict-free LALR(1) table and the parser reports this.
Proof. By Lemma 7 the driver stops, at line L16 or line L17. By Lemma 6 it stops at line L16 when , and by Lemma 5 it stops at line L16 only when , with a parse tree. The table of lines L1 to L10 is determined by , so a conflict means that is not LALR(1).