primaryPhase method

RepairCandidate primaryPhase(
  1. int error_token
)

Implementation

RepairCandidate primaryPhase(int error_token) {
  //
  // Initialize the buffer.
  //
  var i = (nextStackTop >= 0 ? 3 : 2);
  buffer[i] = error_token;

  for (var j = i; j > 0; j--) {
    buffer[j - 1] = tokStream.getPrevious(buffer[j]);
  }

  for (var k = i + 1; k < BUFF_SIZE; k++) {
    buffer[k] = tokStream.getNext(buffer[k - 1]);
  }

  //
  // If NEXT_STACK_TOP > 0 then the parse was successful on CURRENT_TOKEN
  // and the error was detected on the successor of CURRENT_TOKEN. In
  // that case, first check whether or not primary recovery is
  // possible on next_stack ...
  //
  var repair = PrimaryRepairInfo();
  if (nextStackTop >= 0) {
    repair.bufferPosition = 3;
    checkPrimaryDistance(repair, nextStack, nextStackTop);
  }

  //
  // ... Try primary recovery on the current token and compare
  // the quality of this recovery to the one on the next token...
  //
  var base_repair = PrimaryRepairInfo(repair);
  base_repair.bufferPosition = 2;
  checkPrimaryDistance(base_repair, stateStack, stateStackTop);
  if (base_repair.distance > repair.distance ||
      base_repair.misspellIndex > repair.misspellIndex) repair = base_repair;

  //
  // Finally, if prev_stack_top >= 0 try primary recovery on
  // the prev_stack configuration and compare it to the best
  // recovery computed thus far.
  //
  if (prevStackTop >= 0) {
    var prev_repair = PrimaryRepairInfo(repair);
    prev_repair.bufferPosition = 1;
    checkPrimaryDistance(prev_repair, prevStack, prevStackTop);
    if (prev_repair.distance > repair.distance ||
        prev_repair.misspellIndex > repair.misspellIndex) {
      repair = prev_repair;
    }
  }

  //
  // Before accepting the best primary phase recovery obtained,
  // ensure that we cannot do better with a similar secondary
  // phase recovery.
  //
  var candidate = RepairCandidate();
  if (nextStackTop >= 0) // next_stack available
  {
    if (secondaryCheck(nextStack, nextStackTop, 3, repair.distance)) {
      return candidate;
    }
  } else if (secondaryCheck(stateStack, stateStackTop, 2, repair.distance)) {
    return candidate;
  }

  //
  // First, adjust distance if the recovery is on the error token;
  // it is important that the adjustment be made here and not at
  // each primary trial to prevent the distance tests from being
  // biased in favor of deferred recoveries which have access to
  // more input tokens...
  //
  repair.distance = repair.distance - repair.bufferPosition + 1;

  //
  // ...Next, adjust the distance if the recovery is a deletion or
  // (some form of) substitution...
  //
  if (repair.code == INVALID_CODE ||
      repair.code == DELETION_CODE ||
      repair.code == SUBSTITUTION_CODE ||
      repair.code == MERGE_CODE) repair.distance--;

  //
  // ... After adjustment, check if the most successful primary
  // recovery can be applied.  If not, continue with more radical
  // recoveries...
  //
  if (repair.distance < MIN_DISTANCE) return candidate;

  //
  // When processing an insertion error, if the token preceeding
  // the error token is not available, we change the repair code
  // into a BEFORE_CODE to instruct the reporting routine that it
  // indicates that the repair symbol should be inserted before
  // the error token.
  //
  if (repair.code == INSERTION_CODE) {
    if (tokStream.getKind(buffer[repair.bufferPosition - 1]) == 0) {
      repair.code = BEFORE_CODE;
    }
  }

  //
  // Select the proper sequence of states on which to recover,
  // update stack accordingly and call diagnostic routine.
  //
  if (repair.bufferPosition == 1) {
    stateStackTop = prevStackTop;
    ArrayList.copy(prevStack, 0, stateStack, 0, stateStackTop + 1);
  } else if (nextStackTop >= 0 && repair.bufferPosition >= 3) {
    stateStackTop = nextStackTop;
    ArrayList.copy(nextStack, 0, stateStack, 0, stateStackTop + 1);
    locationStack[stateStackTop] = buffer[3];
  }

  return primaryDiagnosis(repair);
}