checkPrimaryDistance method

void checkPrimaryDistance(
  1. PrimaryRepairInfo repair,
  2. List<int> stck,
  3. int stack_top
)

Implementation

void checkPrimaryDistance(
    PrimaryRepairInfo repair, List<int> stck, int stack_top) {
  //
  //  First, try scope recovery.
  //
  var scope_repair = PrimaryRepairInfo(repair);
  scopeTrial(scope_repair, stck, stack_top);
  if (scope_repair.distance > repair.distance) repair.copy(scope_repair);

  //
  //  Next, try merging the error token with its successor.
  //
  var symbol = mergeCandidate(stck[stack_top], repair.bufferPosition);
  if (symbol != 0) {
    var j = parseCheck(stck, stack_top, symbol, repair.bufferPosition + 2);
    if ((j > repair.distance) ||
        (j == repair.distance && repair.misspellIndex < 10)) {
      repair.misspellIndex = 10;
      repair.symbol = symbol;
      repair.distance = j;
      repair.code = MERGE_CODE;
    }
  }

  //
  // Next, try deletion of the error token.
  //
  var j = parseCheck(
      stck,
      stack_top,
      tokStream.getKind(buffer[repair.bufferPosition + 1]),
      repair.bufferPosition + 2);
  var k = (tokStream.getKind(buffer[repair.bufferPosition]) == EOLT_SYMBOL &&
          tokStream.afterEol(buffer[repair.bufferPosition + 1])
      ? 10
      : 0);
  if (j > repair.distance ||
      (j == repair.distance && k > repair.misspellIndex)) {
    repair.misspellIndex = k;
    repair.code = DELETION_CODE;
    repair.distance = j;
  }

  //
  // Update the error configuration by simulating all reduce and
  // goto actions induced by the error token. Then assign the top
  // most state of the new configuration to next_state.
  //
  var next_state = stck[stack_top], max_pos = stack_top;
  tempStackTop = stack_top - 1;

  tokStream.reset(buffer[repair.bufferPosition + 1]);
  var tok = tokStream.getKind(buffer[repair.bufferPosition]),
      act = tAction(next_state, tok);
  while (act <= NUM_RULES) {
    do {
      var lhs_symbol = lhs(act);
      tempStackTop -= (rhs(act) - 1);
      act = (tempStackTop > max_pos
          ? tempStack[tempStackTop]
          : stck[tempStackTop]);
      act = ntAction(act, lhs_symbol);
    } while (act <= NUM_RULES);
    max_pos = max_pos < tempStackTop ? max_pos : tempStackTop;
    tempStack[tempStackTop + 1] = act;
    next_state = act;
    act = tAction(next_state, tok);
  }

  //
  //  Next, place the list of candidates in proper order.
  //
  var root = 0;
  for (var i = asi(next_state); asr(i) != 0; i++) {
    symbol = asr(i);
    if (symbol != EOFT_SYMBOL && symbol != ERROR_SYMBOL) {
      if (root == 0) {
        list[symbol] = symbol;
      } else {
        list[symbol] = list[root];
        list[root] = symbol;
      }
      root = symbol;
    }
  }

  if (stck[stack_top] != next_state) {
    for (var i = asi(stck[stack_top]); asr(i) != 0; i++) {
      symbol = asr(i);
      if (symbol != EOFT_SYMBOL &&
          symbol != ERROR_SYMBOL &&
          list[symbol] == 0) {
        if (root == 0) {
          list[symbol] = symbol;
        } else {
          list[symbol] = list[root];
          list[root] = symbol;
        }
        root = symbol;
      }
    }
  }

  var head = list[root];
  list[root] = 0;
  root = head;

  //
  //  Next, try insertion for each possible candidate available in
  // the current state, except EOFT and ERROR_SYMBOL.
  //
  symbol = root;
  while (symbol != 0) {
    var m = parseCheck(stck, stack_top, symbol, repair.bufferPosition),
        n = (symbol == EOLT_SYMBOL &&
                tokStream.afterEol(buffer[repair.bufferPosition])
            ? 10
            : 0);
    if (m > repair.distance ||
        (m == repair.distance && n > repair.misspellIndex)) {
      repair.misspellIndex = n;
      repair.distance = m;
      repair.symbol = symbol;
      repair.code = INSERTION_CODE;
    }

    symbol = list[symbol];
  }

  //
  //  Next, Try substitution for each possible candidate available
  // in the current state, except EOFT and ERROR_SYMBOL.
  //
  symbol = root;
  while (symbol != 0) {
    var m = parseCheck(stck, stack_top, symbol, repair.bufferPosition + 1),
        n = (symbol == EOLT_SYMBOL &&
                tokStream.afterEol(buffer[repair.bufferPosition + 1])
            ? 10
            : misspell(symbol, buffer[repair.bufferPosition]));
    if (m > repair.distance ||
        (m == repair.distance && n > repair.misspellIndex)) {
      repair.misspellIndex = n;
      repair.distance = m;
      repair.symbol = symbol;
      repair.code = SUBSTITUTION_CODE;
    }

    var s = symbol;
    symbol = list[symbol];
    list[s] = 0; // reset element
  }

  //
  // Next, we try to insert a nonterminal candidate in front of the
  // error token, or substituting a nonterminal candidate for the
  // error token. Precedence is given to insertion.
  //
  for (var nt_index = nasi(stck[stack_top]);
      nasr(nt_index) != 0;
      nt_index++) {
    symbol = nasr(nt_index) + NT_OFFSET;
    var n = parseCheck(stck, stack_top, symbol, repair.bufferPosition + 1);
    if (n > repair.distance) {
      repair.misspellIndex = 0;
      repair.distance = n;
      repair.symbol = symbol;
      repair.code = INVALID_CODE;
    }

    n = parseCheck(stck, stack_top, symbol, repair.bufferPosition);
    if (n > repair.distance ||
        (n == repair.distance && repair.code == INVALID_CODE)) {
      repair.misspellIndex = 0;
      repair.distance = n;
      repair.symbol = symbol;
      repair.code = INSERTION_CODE;
    }
  }

  return;
}