Proofs: Parsing table
These are the human proofs of Parsing table, at full length.
Correctness of the parsing table operations and of the LR driver full
This proof shows: correctness.
We prove two claims about the operations of the parsing table page: the cells and the conflict record are exact, and the LR driver is sound for every deterministic table whose shift and goto entries come from the LR(0) automaton and whose reductions sit at completed items.
Notation. The grammar is , augmented with as production 0, where occurs on no right side. Each state of the LR(0) automaton is a set of items, is the closure of , and is its goto function. The input is followed by .
Part 1: the cells and the conflict record
Claim. After any sequence of ADD calls on an initially empty table, for every cell :
- is the list of distinct actions passed to ADD for , in the order of their first addition;
- is in the conflict set exactly when that list has two or more elements.
Proof. By induction on the number of calls. Both hold for the empty table: every cell is the empty list and the conflict set is empty. Consider a call ; cells other than and their membership in the conflict set do not change. If is empty, line L1 makes it , which is the list of distinct actions added to it, and the list has one element, so the cell is correctly not in the conflict set. If is not empty and already holds , nothing changes, and the list of distinct actions is also unchanged. Otherwise line L2 appends , which is a new distinct action added after all the others, so the order of first addition is kept; the list now has at least two elements and L2 puts into the conflict set. In each case both statements hold after the call.
RESOLVE. Lines L4 and L5 visit exactly the cells of the conflict set, and give each one at most one action; line L6 empties the set. By part 2 of the claim, the cells outside the set had at most one action before the call and are not touched. So after RESOLVE every cell has at most one action and the conflict set is empty, which agrees with part 2. A deterministic table is one whose conflict set is empty, and only on such a table does LOOKUP in L8 return at most one action.
Part 2: soundness of the LR driver
Let be a deterministic table in which
- (a) every entry shift in and goto in has or ;
- (b) every entry reduce in row has the completed item in , with ;
- (c) accept appears only in the column of and only in rows that contain .
The SLR(1), LALR(1) and canonical LR(1) constructions all satisfy (a) to (c) after mapping LR(1) states to their cores, whatever lookaheads they attach and whichever action RESOLVE keeps, because resolution only removes actions.
Claim. If the driver of lines L7 to L11 accepts , then .
Invariant. Before each iteration of L8, the stack is , there are symbols with for , and , where is the input consumed so far.
Initialization. Line L7 sets the stack to with and ; the empty string derives the empty string.
Shift (L9). The entry is shift in , so by (a) . Set ; then by appending one terminal to the derivation.
Reduce (L10). The entry is reduce with . By (b), . Every item of a state other than has been reached by goto, and goto moves the dot over the symbol it reads; items of the form come from closure and have nothing before the dot. So if then the item in arose from items in for , and in particular and . Hence popping states leaves , and the symbols derive . The driver then pushes the goto entry of , which by (a) is , so the invariant holds with . If the cell has no goto entry the driver rejects, which does not affect soundness.
Accept (L11). Accept is read in the column of , so by (c) all of has been consumed, , and contains . First, no goto leads to : an item in either has its dot after at least one symbol or was added by closure, and closure adds only items with , because occurs on no right side; so the item of lies in no goto target. Hence is the only state that contains , and the stack holds only at the bottom. Now has its dot after a symbol, so , and by the argument of the reduce case it came from with . Then , which sits only at the bottom, so and . The invariant gives .
So every accepted string is in .
What is not claimed. The converse, that the driver accepts every and in steps, needs the lookaheads to be correct and fails for some resolution policies: resolving the conflict of the dangling else in favour of the reduction, for instance, makes some sentences unparsable. For conflict-free SLR(1), LALR(1) and canonical LR(1) tables the converse is proved on the pages of those methods; the tests of this page check it on several hundred random grammars against a brute-force enumeration of up to length 4, and check soundness for tables resolved by random choices. ∎