Proofs: Canonical LR(1) parsing
These are the human proofs of Canonical LR(1) parsing, at full length.
With a table free of conflicts, the canonical LR(1) parser stops after O(n) steps on every input full
This proof shows: time.worst, space.extra, time.build, space.table.
We use the notation and Lemmas 1 to 4 and Theorem 2 of the correctness proof. The grammar is fixed, has no useless symbols, and its table has no conflict. Let be the number of states, the number of nonterminals, and the largest length of a right side. A step is one pass through the loop of lines L19 to L24.
Lemma A (a run on a sentence). Let be any input, and let the parser make at least steps on it. Let be the input read before step and the next symbol then. There is a sentence that begins with followed by (or if ) such that the run on begins with the same steps.
Proof. Step uses an entry of ACTION, where is the string of stack symbols. The entry comes from an item of , which by Lemma 4 is valid for through with . By Lemma 3, , and derives some terminal string , so is a sentence. For a shift, begins with , so does; for a reduce or accept, and is the first symbol of . The first steps read only and look only at symbols of and at , so they are the same on .
Lemma B (small parse trees). Let be the unique parse tree of a sentence (unique by Theorem 2). A subtree of whose yield is empty has fewer than nodes. A subtree with a yield of length has at most inner nodes, where .
Proof. If a path in a subtree with empty yield had two nodes with the same label , replacing the subtree of the upper one by the subtree of the lower one would give a second parse tree of the same sentence. So each path has at most inner nodes, each with at most children, and the subtree has at most nodes.
For a yield of length , the spans of the nodes with a nonempty yield form a laminar family of nonempty intervals of positions, which has at most members. Two nodes with the same nonempty span are an ancestor and a descendant, and every node between them has that span too. If two of them had the same label, removing the part between them would give a second tree of the same sentence. So each span has at most nodes, and there are at most nodes with a nonempty yield. Every other inner node lies in a maximal subtree with empty yield, whose root is a child of a node with a nonempty yield. There are at most such subtrees, each with fewer than nodes. The total is at most .
Lemma C (short runs of empty symbols). At each step on any input, a block of consecutive stack symbols that all derive in the run (their part of in Lemma 3 is empty) has fewer than symbols.
Proof. Let the stack symbols be , and let be such a block. By Lemma 3, the input read after was pushed is the part of derived from . So no shift happened between the push of (or the start, if ) and the push of , and the lookahead stayed the same. Let be the time just after the push of , for . Between and the end, the stack never becomes shorter than , because is still on it.
Suppose that the top states at and are the same state , for some . From on, as long as no shift happens and the stack stays above height , each action depends only on the states above height , on , and on . So from the parser repeats, one level higher, the steps it made from , reaches the top state again without a shift, and does so forever. Take the sentence of Lemma A for the current step: its run agrees with this run up to the current step and has the same lookahead at this position, so it is infinite. This contradicts Theorem 2. Hence the top states at are distinct, and .
Theorem (time and space of the parse). On an input of length , the parser stops after at most steps. The stack never holds more than states.
Proof. Take any step , with stack symbols , input read , and the sentence of Lemma A with its tree . Since the run on begins with the same steps, Theorem 2 says that each reduction so far made an inner node of , and that these nodes are exactly the inner nodes of the subtrees of rooted at . Their yields split . At most of the have a nonempty yield, and by Lemma C the others form at most blocks of fewer than symbols each. So , plus the state 0 at the bottom, which bounds the stack. By Lemma B, the subtrees with nonempty yields have at most inner nodes in total, and the others at most . There are at most shifts, because is never shifted, and at most one accept, so is bounded by the number in the statement. This bound does not depend on , so the run is finite. A step does work, apart from popping at most states, so the time is for the fixed grammar.
The constant in grows with , which can be exponential in . For a sentence the count is smaller: by Theorem 2 the steps are the shifts, the inner nodes of the tree, and the accept, and by Lemma B there are at most inner nodes.
The cost of the construction. Let be the number of LR(1) items. A production has dot positions, so . A CLOSURE puts each of at most items on the work list once. For an item it computes FIRST in time from the FIRST sets, which are computed once in advance, and then for each of at most lookaheads it scans the productions of , work. So one CLOSURE takes time. A state has at most symbols after a dot; for each, line L17 forms the kernel in time and closes it, and line L6 looks the set up in a trie of flag vectors of length , in time. A state therefore costs , and lines L1 to L8 cost . Lines L9 to L13 look at each item of each state once, time. The ACTION table has entries and the GOTO table entries, so the tables take space.
The canonical LR(1) parser outputs only rightmost derivations, and with a table free of conflicts it parses every sentence full
This proof shows: correctness.
We use the augmented grammar with and the end marker . The item sets are the list built by lines L1 to L8, and is the transition function of line L7. For a string of grammar symbols, write for the state reached from state 0 by following on , when all these transitions are defined. FIRST denotes the set computed from the FIRST sets of the symbols, as in line L15. For every grammar it contains each terminal that begins a terminal string derived from : the fixpoint adds a terminal for each way it can begin such a string. A derivation step is rightmost when it rewrites the rightmost nonterminal of the form.
Lemma 1 (shape of items). If the item is in , then is a suffix of . If moreover , then is in , where .
Proof. By induction on . The items of a CLOSURE are the given items and items with the dot at the left end, which have . For the state is , whose only item that is not added by closure is , so every item has . For , the state is GOTO by line L5. By line L17 an item with in it comes from an item of with . By the induction hypothesis is a suffix of , so is a suffix of .
Lemma 2 (validity). If the item is valid for , then is defined and contains the item.
Proof. The item is valid through a rightmost derivation with and the first symbol of . Let be the number of steps of . We use induction on the pair in lexicographic order.
Case . The item is valid for through the same derivation, with the same and a shorter . By the induction hypothesis it is in . So follows a dot in that state, line L7 defines on , and line L17 puts into GOTO.
Case and . Then , so , , and . The only production of is , and is in by line L1.
Case and . Here . Look at the step of the derivation that created this occurrence of : a step by a production , where is a terminal string because the step is rightmost. After this step, a rightmost derivation rewrites the nonterminals right of before itself, and it does not touch the symbols left of until is rewritten. So the derivation has the form
with , and . The item , with the first symbol of , is valid for through a derivation of with fewer than steps. By the induction hypothesis, it is in . Now is the first symbol of . If , then begins a string derived from ; if , then and . In both cases FIRST. So line L15 adds for the production to the closure that forms .
Lemma 3 (invariant of the driver). At each test of line L20, let the stack hold the states and let be the part of read so far. Then , there are symbols with for each , so that , and the reductions output so far, applied in reverse order as rewriting steps, derive from . In any form of this derivation followed by the rest of , each step rewrites the rightmost nonterminal.
Proof. By induction on the number of steps. At the start, , , and there are no reductions. A shift on the terminal pushes (line L10 and line L21), so and grows by ; the derivation is unchanged. A reduce by is in the table because some item is in (line L11). By Lemma 1, , and holds , so is defined and line L22 pushes it. The new symbols are , and the new first step rewrites this to . Every symbol right of this , in the form followed by , is a terminal of , so the step is rightmost. The old derivation follows it.
Theorem 1 (soundness). If LR-PARSE returns an output, the output, read backwards, is a rightmost derivation . This holds for every grammar, also when conflicts were resolved in any way.
Proof. Accept happens at line L23, so holds and the next symbol is , so . By Lemma 1, and holds . This item is the kernel of , it is not added by any closure because is on no right side, and it is not the kernel of any GOTO, whose kernels have the dot after a symbol. So , which happens only at the bottom of the stack, because every pushed state is a GOTO and does not hold this item. Hence , and Lemma 3 says that the output, backwards, derives from by rightmost steps.
Theorem 2 (completeness). Assume that no entry of ACTION got two actions. If and is a parse tree of with root , then LR-PARSE accepts, and the reductions it outputs are the inner nodes of in postorder. In particular has only one parse tree, so is unambiguous.
Proof. Add a root above . The events of the tree are its terminal leaves and its inner nodes other than , in postorder. Make a shift event for each terminal leaf and a reduce event for each inner node, and a final accept event. We show by induction that the -th step of the parser is the -th event.
Before an event , call a node done if it comes before in postorder. Let be the set of nodes that are not done but have a done descendant or are on the path from the root to . These are exactly the proper ancestors of , together with itself if is an inner node. For each node with production , let be its children that are done, which come before its children that are not done. Let be the concatenation of these , from the root down. The induction hypothesis is that the stack symbols are and that the input read is the yield of the done nodes, which is a prefix of .
The tree gives, for each with as above, a rightmost derivation . Expand the nodes of the path from the root to , and before each of them expand fully all the subtrees to the right of the path. Then is the concatenation of the done children of the ancestors of , is the yield of the tree to the right of , and is a prefix of . So the item , with the first symbol of , is valid for .
- If is a leaf with terminal , its parent is the lowest node of , and it has with . The next input symbol is , because the done leaves are exactly the leaves before . The item is valid for , so by Lemma 2 it is in , and line L10 put a shift into ACTION. With no conflict this is the only action, so the parser shifts , and the hypothesis holds before the next event.
- If is an inner node with production , all its children are done, so is the lowest node of with the item , valid for . Here is the first symbol after the yield of , which is the next input symbol. By Lemma 2 and line L11, ACTION is reduce , and it is the only action. The parser pops the symbols of and pushes , which is the stack of the next event, where is done.
- If all nodes but are done, then and the input read is , and is valid for . By Lemma 2 and line L12, the action on is accept.
So the parser accepts after the events of , and outputs its inner nodes in postorder. The parser is deterministic and its run depends only on . Two different parse trees of would give two different postorders, so they would give two different runs, which is impossible.
Lemma 4 (state items are valid). If has no useless symbols, every item of is valid for .
Proof. When every nonterminal derives a terminal string, the computed FIRST is exactly the set of terminals that begin a terminal string derived from : each terminal that the fixpoint adds begins a sentential form derived from , and the rest of that form derives a terminal string. We use induction on the order in which the construction adds items. The item is valid for . A GOTO item of comes from of , which is valid for ; the same derivation makes the new item valid for . A closure item comes from , valid for through , and FIRST. Take a terminal string with such that is the first symbol of ; it exists by the exactness of FIRST. Then
is rightmost, because lies right of . So is valid for .
Theorem 3 (rejection). Assume that no entry of ACTION got two actions and that has no useless symbols. If , LR-PARSE returns error after finitely many steps.
Proof. By Theorem 1 the parser never accepts . The theorem of the complexity proof, which uses only Lemmas 1 to 4 and Theorem 2, shows that on every input the run stops after steps. A run that stops without accepting ends at line L24.
Theorems 1, 2 and 3 together say: with a table free of conflicts, for a grammar without useless symbols, LR-PARSE returns a rightmost derivation of when and error otherwise. Theorem 2 alone shows that a grammar with such a table is unambiguous.