repairable method
Implementation
bool repairable(int error_token) {
//
// Allocate configuration stack.
//
var configuration_stack = ConfigurationStack(prs);
//
// Keep parsing until we successfully reach the end of file or
// an error is encountered. The list of actions executed will
// be stored in the "action" tuple.
//
var start_token = tokStream.peek(),
final_token = tokStream.getStreamLength(), // unreachable
curtok = 0,
current_kind = ERROR_SYMBOL,
act = tAction(stateStack[stateStackTop], current_kind);
for (;;) {
if (act <= NUM_RULES) {
stateStackTop--;
act = process_backtrack_reductions(act);
} else if (act > ERROR_ACTION) {
curtok = tokStream.getToken();
if (curtok > final_token) return true;
current_kind = tokStream.getKind(curtok);
act = process_backtrack_reductions(act - ERROR_ACTION);
} else if (act < ACCEPT_ACTION) {
curtok = tokStream.getToken();
if (curtok > final_token) return true;
current_kind = tokStream.getKind(curtok);
} else if (act == ERROR_ACTION) {
var configuration = configuration_stack.pop();
if (configuration == null) {
act = ERROR_ACTION;
} else {
stateStackTop = configuration.stack_top;
configuration.retrieveStack(stateStack);
act = configuration.act;
curtok = configuration.curtok;
if (curtok == 0) {
current_kind = ERROR_SYMBOL;
tokStream.reset(start_token);
} else {
current_kind = tokStream.getKind(curtok);
tokStream.reset(tokStream.getNext(curtok));
}
continue;
}
break;
} else if (act > ACCEPT_ACTION) {
if (configuration_stack.findConfiguration(
stateStack, stateStackTop, curtok)) {
act = ERROR_ACTION;
} else {
configuration_stack.push(
stateStack, stateStackTop, act + 1, curtok, 0);
act = prs.baseAction(act);
}
continue;
} else {
break;
} // assert(act == ACCEPT_ACTION);
try {
//
// We consider a configuration to be acceptable for recovery
// if we are able to consume enough symbols in the remainining
// tokens to reach another potential recovery point past the
// original error token.
//
if ((curtok > error_token) &&
(final_token == tokStream.getStreamLength())) {
//
// If the ERROR_SYMBOL is a valid Action Adjunct in the state
// "act" then we set the terminating token as the successor of
// the current token. I.e., we have to be able to parse at least
// two tokens past the resynch point before we claim victory.
//
if (recoverableState(act)) {
final_token = skipTokens ? curtok : tokStream.getNext(curtok);
}
}
stateStack[++stateStackTop] = act;
} on RangeError {
reallocateStateStack();
stateStack[stateStackTop] = act;
}
act = tAction(act, current_kind);
}
//
// If we can reach the end of the input successfully, we claim victory.
//
return (act == ACCEPT_ACTION);
}