Recover:
PROC = {
ModeMap: ARRAY Position OF ParsingMode = [$aTree, $bTree];
stack: StackRep;
treeLimit ← treeSize - checkSize;
hashTable^ ← ALL[nullIndex];
rTop ← nullIndex; nextNode ← maxNode ← 1;
best.nAccepted ← 0; best.nPassed ← 1; best.mode ← $aTree;
scanBuffer[0] ← lastToken;
scanBuffer[1] ← P1.Token[inputSymbol, inputValue, inputLoc];
scanBase ← 1; scanLimit ← 2;
THROUGH [1 .. maxScanLimit) DO Advance[] ENDLOOP;
FOR i:
NAT
IN [0 .. top)
DO
rTop ← Allocate[rTop, rTop, 0, s[i]];
IF track THEN DisplayNode[rTop];
ENDLOOP;
parseMode ← $bTree;
levelStart[$before][0] ← rTop ← FindNode[rTop, rTop, s[top]];
tree[rTop].bLeaf ← TRUE;
levelEnd[$before][0] ← nextNode;
parseMode ← $aTree;
stack ← ParseStep[[leaf:rTop, extension:nullState], lastToken.class];
rTop ← FindNode[stack.leaf, rTop, stack.extension];
tree[rTop].symbol ← lastToken.class;
tree[rTop].aLeaf ← tree[rTop].bLeaf ← TRUE;
levelStart[$after][0] ← rTop; levelEnd[$after][0] ← nextNode;
IF track THEN DisplayNode[rTop];
FOR level: Length
IN [1 .. Length.
LAST]
DO
FOR place: Position
IN Position
DO
parseMode ← ModeMap[place];
IF place = $before THEN UnDiscard[];
try simple insertion (inserts=level)
levelStart[place][level] ← nextNode;
IF GrowTree[place, level ! TreeFull => {CONTINUE}] THEN GO TO found;
levelEnd[place][level] ← nextNode;
try discards followed by 0 or more insertions
THROUGH [1 .. level)
DO
Discard[]; IF CheckTree[place, level] THEN GO TO found ENDLOOP;
Discard[];
IF place = $after THEN Advance[];
FOR inserts:
NAT
IN [0 .. level]
DO
IF CheckTree[place, inserts] THEN GO TO found ENDLOOP;
undo discards at this level
THROUGH [1..level] DO UnDiscard[] ENDLOOP;
IF place = $before THEN Discard[];
ENDLOOP;
REPEAT
found => NULL;
FINISHED => {
threshold: NAT ← (minScanLimit+maxScanLimit)/2;
THROUGH [1..Length.LAST] DO Discard[]; Advance[] ENDLOOP;
UNTIL scanBase > discardLimit
DO
IF best.nAccepted >= threshold THEN GO TO found;
Discard[];
FOR inserts:
NAT
IN Length
DO
FOR place: Position
IN Position
DO
parseMode ← ModeMap[place];
IF place = $before THEN UnDiscard[];
IF CheckTree[place, inserts] THEN GO TO found;
IF place = $before THEN Discard[];
ENDLOOP;
ENDLOOP;
Advance[];
threshold ← IF threshold > minScanLimit THEN threshold-1 ELSE minScanLimit;
REPEAT
found => NULL;
FINISHED =>
IF best.nAccepted < minScanLimit THEN {best.mode ← $aTree; best.nPassed ← 1};
ENDLOOP};
ENDLOOP};
}.