backtrackParseUpToError method

void backtrackParseUpToError(
  1. int initial_token,
  2. int error_token
)

Implementation

void backtrackParseUpToError(int initial_token, 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(),
      curtok = (initial_token > 0 ? initial_token : tokStream.getToken()),
      current_kind = tokStream.getKind(curtok),
      act = tAction(stateStack[stateStackTop], current_kind);

  tokens.add(curtok);
  locationStack[stateStackTop] = tokens.size();
  actionStack[stateStackTop] = action.size();

  for (;;) {
    //
    // if the parser needs to stop processing,
    // it may do so here.
    //
    if (monitor != null && monitor!.isCancelled()) return;

    if (act <= NUM_RULES) {
      action.add(act); // save this reduce action
      stateStackTop--;
      act = process_backtrack_reductions(act);
    } else if (act > ERROR_ACTION) {
      action.add(act); // save this shift-reduce action
      curtok = tokStream.getToken();
      current_kind = tokStream.getKind(curtok);
      tokens.add(curtok);
      act = process_backtrack_reductions(act - ERROR_ACTION);
    } else if (act < ACCEPT_ACTION) {
      action.add(act); // save this shift action
      curtok = tokStream.getToken();
      current_kind = tokStream.getKind(curtok);
      tokens.add(curtok);
    } else if (act == ERROR_ACTION) {
      if (curtok != error_token) {
        var configuration = configuration_stack.pop();
        if (configuration == null) {
          act = ERROR_ACTION;
        } else {
          action.reset(configuration.action_length);
          act = configuration.act;
          var next_token_index = configuration.curtok;
          tokens.reset(next_token_index);
          curtok = tokens.get(next_token_index - 1);
          current_kind = tokStream.getKind(curtok);
          tokStream.reset(curtok == initial_token
              ? start_token
              : tokStream.getNext(curtok));
          stateStackTop = configuration.stack_top;
          configuration.retrieveStack(stateStack);
          locationStack[stateStackTop] = tokens.size();
          actionStack[stateStackTop] = action.size();
          continue;
        }
      }
      break;
    } else if (act > ACCEPT_ACTION) {
      if (configuration_stack.findConfiguration(
          stateStack, stateStackTop, tokens.size())) {
        act = ERROR_ACTION;
      } else {
        configuration_stack.push(
            stateStack, stateStackTop, act + 1, tokens.size(), action.size());
        act = prs.baseAction(act);
      }
      continue;
    } else {
      break;
    } // assert(act == ACCEPT_ACTION);

    stateStack[++stateStackTop] = act; // no need to check if out of bounds
    locationStack[stateStackTop] = tokens.size();
    actionStack[stateStackTop] = action.size();
    act = tAction(act, current_kind);
  }

  // assert(curtok == error_token);

  return;
}