errorRecovery method
Implementation
RepairCandidate errorRecovery(int error_token) {
var prevtok = tokStream.getPrevious(error_token);
//
// Try primary phase recoveries. If not successful, try secondary
// phase recoveries. If not successful and we are at end of the
// file, we issue the end-of-file error and quit. Otherwise, ...
//
var candidate = primaryPhase(error_token);
if (candidate.symbol != 0) return candidate;
candidate = secondaryPhase(error_token);
if (candidate.symbol != 0) return candidate;
//
// At this point, primary and (initial attempt at) secondary
// recovery did not work. We will now get into "panic mode" and
// keep trying secondary phase recoveries until we either find
// a successful recovery or have consumed the remaining input
// tokens.
//
if (tokStream.getKind(error_token) != EOFT_SYMBOL) {
while (tokStream.getKind(buffer[BUFF_UBOUND]) != EOFT_SYMBOL) {
candidate = secondaryPhase(buffer[MAX_DISTANCE - MIN_DISTANCE + 2]);
if (candidate.symbol != 0) return candidate;
}
}
//
// If no successful recovery is found and we have reached the
// end of the file, check whether or not any scope recovery is
// applicable at the end of the file after discarding some
// states.
//
var scope_repair = PrimaryRepairInfo();
scope_repair.bufferPosition = BUFF_UBOUND;
for (var top = stateStackTop; top >= 0; top--) {
scopeTrial(scope_repair, stateStack, top);
if (scope_repair.distance > 0) break;
}
//
// If any scope repair was successful, emit the message now
//
for (var i = 0; i < scopeStackTop; i++) {
emitError(SCOPE_CODE, -scopeIndex[i], locationStack[scopePosition[i]],
buffer[1], nonterminalIndex(scopeLhs(scopeIndex[i])));
}
//
// If the original error_token was already pointing to the EOF, issue the EOF-reached message.
//
if (tokStream.getKind(error_token) == EOFT_SYMBOL) {
emitError(EOF_CODE, terminalIndex(EOFT_SYMBOL), prevtok, prevtok);
} else {
//
// We reached the end of the file while panicking. Delete all
// remaining tokens in the input.
//
var i = 0;
for (i = BUFF_UBOUND; tokStream.getKind(buffer[i]) == EOFT_SYMBOL; i--) {
;
}
emitError(DELETION_CODE, terminalIndex(tokStream.getKind(error_token)),
error_token, buffer[i]);
}
//
// Create the "failed" candidate and return it.
//
candidate.symbol = 0;
candidate.location = buffer[BUFF_UBOUND]; // point to EOF
return candidate;
}