secondaryPhase method

RepairCandidate secondaryPhase(
  1. int error_token
)

Implementation

RepairCandidate secondaryPhase(int error_token) {
  var repair = SecondaryRepairInfo(),
      misplaced_repair = SecondaryRepairInfo();

  //
  // If the next_stack is available, try misplaced and secondary
  // recovery on it first.
  //
  var next_last_index = 0;
  if (nextStackTop >= 0) {
    int save_location;

    buffer[2] = error_token;
    buffer[1] = tokStream.getPrevious(buffer[2]);
    buffer[0] = tokStream.getPrevious(buffer[1]);

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

    buffer[BUFF_UBOUND] = tokStream.badToken(); // elmt not available

    //
    // If we are at the end of the input stream, compute the
    // index position of the first EOFT symbol (last useful
    // index).
    //
    for (next_last_index = MAX_DISTANCE - 1;
        next_last_index >= 1 &&
            tokStream.getKind(buffer[next_last_index]) == EOFT_SYMBOL;
        next_last_index--) {
      ;
    }
    next_last_index = next_last_index + 1;

    save_location = locationStack[nextStackTop];
    locationStack[nextStackTop] = buffer[2];
    misplaced_repair.numDeletions = nextStackTop;
    misplacementRecovery(
        misplaced_repair, nextStack, nextStackTop, next_last_index, true);
    if (misplaced_repair.recoveryOnNextStack) misplaced_repair.distance++;

    repair.numDeletions = nextStackTop + BUFF_UBOUND;
    secondaryRecovery(repair, nextStack, nextStackTop, next_last_index, true);
    if (repair.recoveryOnNextStack) repair.distance++;

    locationStack[nextStackTop] = save_location;
  } else // next_stack not available, initialize ...
  {
    misplaced_repair.numDeletions = stateStackTop;
    repair.numDeletions = stateStackTop + BUFF_UBOUND;
  }

  //
  // Try secondary recovery on the "stack" configuration.
  //
  buffer[3] = error_token;

  buffer[2] = tokStream.getPrevious(buffer[3]);
  buffer[1] = tokStream.getPrevious(buffer[2]);
  buffer[0] = tokStream.getPrevious(buffer[1]);

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

  int last_index;
  for (last_index = MAX_DISTANCE - 1;
      last_index >= 1 && tokStream.getKind(buffer[last_index]) == EOFT_SYMBOL;
      last_index--) {
    ;
  }
  last_index++;

  misplacementRecovery(
      misplaced_repair, stateStack, stateStackTop, last_index, false);

  secondaryRecovery(repair, stateStack, stateStackTop, last_index, false);

  //
  // If a successful misplaced recovery was found, compare it with
  // the most successful secondary recovery.  If the misplaced
  // recovery either deletes fewer symbols or parse-checks further
  // then it is chosen.
  //
  if (misplaced_repair.distance > MIN_DISTANCE) {
    if (misplaced_repair.numDeletions <= repair.numDeletions ||
        (misplaced_repair.distance - misplaced_repair.numDeletions) >=
            (repair.distance - repair.numDeletions)) {
      repair.code = MISPLACED_CODE;
      repair.stackPosition = misplaced_repair.stackPosition;
      repair.bufferPosition = 2;
      repair.numDeletions = misplaced_repair.numDeletions;
      repair.distance = misplaced_repair.distance;
      repair.recoveryOnNextStack = misplaced_repair.recoveryOnNextStack;
    }
  }

  //
  // If the successful recovery was on next_stack, update: stack,
  // buffer, location_stack and last_index.
  //
  if (repair.recoveryOnNextStack) {
    stateStackTop = nextStackTop;
    ArrayList.copy(nextStack, 0, stateStack, 0, stateStackTop + 1);

    buffer[2] = error_token;
    buffer[1] = tokStream.getPrevious(buffer[2]);
    buffer[0] = tokStream.getPrevious(buffer[1]);

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

    buffer[BUFF_UBOUND] = tokStream.badToken(); // elmt not available

    locationStack[nextStackTop] = buffer[2];
    last_index = next_last_index;
  }

  //
  // Next, try scope recoveries after deletion of one, two, three,
  // four ... buffer_position tokens from the input stream.
  //
  if (repair.code == SECONDARY_CODE || repair.code == DELETION_CODE) {
    var scope_repair = PrimaryRepairInfo();
    for (scope_repair.bufferPosition = 2;
        scope_repair.bufferPosition <= repair.bufferPosition &&
            repair.code != SCOPE_CODE;
        scope_repair.bufferPosition++) {
      scopeTrial(scope_repair, stateStack, stateStackTop);
      var j = (scope_repair.distance == MAX_DISTANCE
              ? last_index
              : scope_repair.distance),
          k = scope_repair.bufferPosition - 1;
      if ((scope_repair.distance - k) > MIN_DISTANCE &&
          (j - k) > (repair.distance - repair.numDeletions)) {
        var i = scopeIndex[scopeStackTop]; // upper bound
        repair.code = SCOPE_CODE;
        repair.symbol = scopeLhs(i) + NT_OFFSET;
        repair.stackPosition = stateStackTop;
        repair.bufferPosition = scope_repair.bufferPosition;
      }
    }
  }

  //
  // If a successful repair was not found, quit!  Otherwise, issue
  // diagnosis and adjust configuration...
  //
  var candidate = RepairCandidate();
  if (repair.code == 0) return candidate;

  secondaryDiagnosis(repair);

  //
  // Update buffer based on number of elements that are deleted.
  //
  switch (repair.code) {
    case MISPLACED_CODE:
      candidate.location = buffer[2];
      candidate.symbol = tokStream.getKind(buffer[2]);
      tokStream.reset(tokStream.getNext(buffer[2]));

      break;

    case DELETION_CODE:
      candidate.location = buffer[repair.bufferPosition];
      candidate.symbol = tokStream.getKind(buffer[repair.bufferPosition]);
      tokStream.reset(tokStream.getNext(buffer[repair.bufferPosition]));

      break;

    default: // SCOPE_CODE || SECONDARY_CODE
      candidate.symbol = repair.symbol;
      candidate.location = buffer[repair.bufferPosition];
      tokStream.reset(buffer[repair.bufferPosition]);

      break;
  }

  return candidate;
}