acceptRecovery method
void
acceptRecovery(
- int error_token
)
Implementation
void acceptRecovery(int error_token) {
//
//
//
// int action_size = action.size();
//
// Simulate parsing actions required for this sequence of scope
// recoveries.
// TODO: need to add action and fix the location_stack?
//
var recovery_action = IntTuple();
for (var k = 0; k <= scopeStackTop; k++) {
var scope_index = scopeIndex[k], la = scopeLa(scope_index);
//
// Compute the action (or set of actions in case of conflicts) that
// can be executed on the scope lookahead symbol. Save the action(s)
// in the action tuple.
//
recovery_action.reset();
var act = tAction(stateStack[stateStackTop], la);
if (act > ACCEPT_ACTION && act < ERROR_ACTION) // conflicting actions?
{
do {
recovery_action.add(baseAction(act++));
} while (baseAction(act) != 0);
} else {
recovery_action.add(act);
}
//
// For each action defined on the scope lookahead symbol,
// try scope recovery. At least one action should succeed!
//
var start_action_size = action.size();
int index;
for (index = 0; index < recovery_action.size(); index++) {
//
// Reset the action tuple each time through this loop
// to clear previous actions that may have been added
// because of a failed call to completeScope.
//
action.reset(start_action_size);
tokStream.reset(error_token);
tempStackTop = stateStackTop - 1;
var max_pos = stateStackTop;
act = recovery_action.get(index);
while (act <= NUM_RULES) {
action.add(act); // save this reduce action
//
// ... Process all goto-reduce actions following
// reduction, until a goto action is computed ...
//
do {
var lhs_symbol = lhs(act);
tempStackTop -= (rhs(act) - 1);
act = (tempStackTop > max_pos
? tempStack[tempStackTop]
: stateStack[tempStackTop]);
act = ntAction(act, lhs_symbol);
} while (act <= NUM_RULES);
if (tempStackTop + 1 >= stateStack.length) reallocateStacks();
max_pos = max_pos < tempStackTop ? max_pos : tempStackTop;
tempStack[tempStackTop + 1] = act;
act = tAction(act, la);
}
//
// If the lookahead symbol is parsable, then we check
// whether or not we have a match between the scope
// prefix and the transition symbols corresponding to
// the states on top of the stack.
//
if (act != ERROR_ACTION) {
nextStackTop = ++tempStackTop;
for (var i = 0; i <= max_pos; i++) {
nextStack[i] = stateStack[i];
}
//
// NOTE that we do not need to update location_stack and
// actionStack here because, once the rules associated with
// these scopes are reduced, all these states will be popped
// from the stack.
//
for (var i = max_pos + 1; i <= tempStackTop; i++) {
nextStack[i] = tempStack[i];
}
if (completeScope(action, scopeSuffix(scope_index))) {
for (var i = scopeSuffix(scopeIndex[k]); scopeRhs(i) != 0; i++) {
// System.err.println("(*) adding token for
// nonterminal at location " + tokens.size());
tokens.add((tokStream as IPrsStream).makeErrorToken(
error_token,
tokStream.getPrevious(error_token),
error_token,
scopeRhs(i)));
}
reportError(scopeIndex[k], tokStream.getPrevious(error_token));
break;
}
}
}
// assert (index < recovery_action.size()); // sanity check!
stateStackTop = nextStackTop;
ArrayList.copy(nextStack, 0, stateStack, 0, stateStackTop + 1);
}
return;
}