repairable method

bool repairable(
  1. int error_token
)

Implementation

bool repairable(int error_token) {
  //
  // Allocate configuration stack.
  //
  var configuration_stack = ConfigurationStack(prs);

  //
  // Keep parsing until we successfully reach the end of file or
  // an error is encountered. The list of actions executed will
  // be stored in the "action" tuple.
  //
  var start_token = tokStream.peek(),
      final_token = tokStream.getStreamLength(), // unreachable
      curtok = 0,
      current_kind = ERROR_SYMBOL,
      act = tAction(stateStack[stateStackTop], current_kind);

  for (;;) {
    if (act <= NUM_RULES) {
      stateStackTop--;
      act = process_backtrack_reductions(act);
    } else if (act > ERROR_ACTION) {
      curtok = tokStream.getToken();
      if (curtok > final_token) return true;
      current_kind = tokStream.getKind(curtok);
      act = process_backtrack_reductions(act - ERROR_ACTION);
    } else if (act < ACCEPT_ACTION) {
      curtok = tokStream.getToken();
      if (curtok > final_token) return true;
      current_kind = tokStream.getKind(curtok);
    } else if (act == ERROR_ACTION) {
      var configuration = configuration_stack.pop();
      if (configuration == null) {
        act = ERROR_ACTION;
      } else {
        stateStackTop = configuration.stack_top;
        configuration.retrieveStack(stateStack);
        act = configuration.act;
        curtok = configuration.curtok;
        if (curtok == 0) {
          current_kind = ERROR_SYMBOL;
          tokStream.reset(start_token);
        } else {
          current_kind = tokStream.getKind(curtok);
          tokStream.reset(tokStream.getNext(curtok));
        }
        continue;
      }
      break;
    } else if (act > ACCEPT_ACTION) {
      if (configuration_stack.findConfiguration(
          stateStack, stateStackTop, curtok)) {
        act = ERROR_ACTION;
      } else {
        configuration_stack.push(
            stateStack, stateStackTop, act + 1, curtok, 0);
        act = prs.baseAction(act);
      }
      continue;
    } else {
      break;
    } // assert(act == ACCEPT_ACTION);
    try {
      //
      // We consider a configuration to be acceptable for recovery
      // if we are able to consume enough symbols in the remainining
      // tokens to reach another potential recovery point past the
      // original error token.
      //
      if ((curtok > error_token) &&
          (final_token == tokStream.getStreamLength())) {
        //
        // If the ERROR_SYMBOL is a valid Action Adjunct in the state
        // "act" then we set the terminating token as the successor of
        // the current token. I.e., we have to be able to parse at least
        // two tokens past the resynch point before we claim victory.
        //
        if (recoverableState(act)) {
          final_token = skipTokens ? curtok : tokStream.getNext(curtok);
        }
      }

      stateStack[++stateStackTop] = act;
    } on RangeError {
      reallocateStateStack();
      stateStack[stateStackTop] = act;
    }

    act = tAction(act, current_kind);
  }

  //
  // If we can reach the end of the input successfully, we claim victory.
  //
  return (act == ACCEPT_ACTION);
}