errorRecovery method

RepairCandidate errorRecovery(
  1. int error_token
)

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;
}