diagnoseEntry2 method

void diagnoseEntry2(
  1. int marker_kind,
  2. int error_token
)

Implementation

void diagnoseEntry2(int marker_kind, int error_token) {
  var action = IntTuple(1 << 18);
  var startTime = currentTimeMillis();
  var errorCount = 0;

  //
  // Compute sequence of actions that leads us to the
  // error_token.
  //
  if (stateStack.isEmpty) {
    reallocateStacks();
  }
  tempStackTop = 0;
  tempStack[tempStackTop] = START_STATE;
  tokStream.reset();
  int current_token, current_kind;
  if (marker_kind == 0) {
    current_token = tokStream.getToken();
    current_kind = tokStream.getKind(current_token);
  } else {
    current_token = tokStream.peek();
    current_kind = marker_kind;
  }

  parseUpToError(action, current_kind, error_token);

  //
  // Start parsing
  //
  stateStackTop = 0;
  stateStack[stateStackTop] = START_STATE;

  tempStackTop = stateStackTop;
  ArrayList.copy(tempStack, 0, stateStack, 0, tempStackTop + 1);

  tokStream.reset();
  if (marker_kind == 0) {
    current_token = tokStream.getToken();
    current_kind = tokStream.getKind(current_token);
  } else {
    current_token = tokStream.peek();
    current_kind = marker_kind;
  }
  locationStack[stateStackTop] = current_token;

  //
  // Process a terminal
  //
  int act;
  do {
    //
    // Synchronize state stacks and update the location stack
    //
    var prev_pos = -1;
    prevStackTop = -1;

    var next_pos = -1;
    nextStackTop = -1;

    var pos = stateStackTop;
    tempStackTop = stateStackTop - 1;
    ArrayList.copy(stateStack, 0, tempStack, 0, stateStackTop + 1);

    var action_index = 0;
    act = action.get(action_index++); // tAction(act, current_kind);

    //
    // When a reduce action is encountered, we compute all REDUCE
    // and associated goto actions induced by the current token.
    // Eventually, a SHIFT, SHIFT-REDUCE, ACCEPT or ERROR action is
    // computed...
    //
    while (act <= NUM_RULES) {
      do {
        tempStackTop -= (rhs(act) - 1);
        act = ntAction(tempStack[tempStackTop], lhs(act));
      } while (act <= NUM_RULES);
      //
      // ... Update the maximum useful position of the
      // (STATE_)STACK, push goto state into stack, and
      // compute next action on current symbol ...
      //
      if (tempStackTop + 1 >= stateStack.length) reallocateStacks();
      pos = pos < tempStackTop ? pos : tempStackTop;
      tempStack[tempStackTop + 1] = act;
      act = action.get(action_index++); // tAction(act, current_kind);
    }

    //
    // At this point, we have a shift, shift-reduce, accept or error
    // action.  STACK contains the configuration of the state stack
    // prior to executing any action on current_token. next_stack contains
    // the configuration of the state stack after executing all
    // reduce actions induced by current_token.  The variable pos indicates
    // the highest position in STACK that is still useful after the
    // reductions are executed.
    //
    while (act > ERROR_ACTION ||
        act < ACCEPT_ACTION) // SHIFT-REDUCE action or SHIFT action ?
    {
      //
      // if the parser needs to stop processing,
      // it may do so here.
      //
      if (monitor != null && monitor!.isCancelled()) {
        return;
      }

      nextStackTop = tempStackTop + 1;
      for (var i = next_pos + 1; i <= nextStackTop; i++) {
        nextStack[i] = tempStack[i];
      }

      for (var k = pos + 1; k <= nextStackTop; k++) {
        locationStack[k] = locationStack[stateStackTop];
      }

      //
      // If we have a shift-reduce, process it as well as
      // the goto-reduce actions that follow it.
      //
      if (act > ERROR_ACTION) {
        act -= ERROR_ACTION;
        do {
          nextStackTop -= (rhs(act) - 1);
          act = ntAction(nextStack[nextStackTop], lhs(act));
        } while (act <= NUM_RULES);
        pos = pos < nextStackTop ? pos : nextStackTop;
      }

      if (nextStackTop + 1 >= stateStack.length) reallocateStacks();

      tempStackTop = nextStackTop;
      nextStack[++nextStackTop] = act;
      next_pos = nextStackTop;

      //
      // Simulate the parser through the next token without
      // destroying STACK or next_stack.
      //
      current_token = tokStream.getToken();
      current_kind = tokStream.getKind(current_token);
      act = action.get(action_index++); // tAction(act, current_kind);
      while (act <= NUM_RULES) {
        //
        // ... Process all goto-reduce actions following
        // reduction, until a goto action is computed ...
        //
        do {
          var lhs_symbol = lhs(act);
          tempStackTop -= (rhs(act) - 1);
          act = (tempStackTop > next_pos
              ? tempStack[tempStackTop]
              : nextStack[tempStackTop]);
          act = ntAction(act, lhs_symbol);
        } while (act <= NUM_RULES);

        //
        // ... Update the maximum useful position of the
        // (STATE_)STACK, push GOTO state into stack, and
        // compute next action on current symbol ...
        //
        if (tempStackTop + 1 >= stateStack.length) reallocateStacks();

        next_pos = next_pos < tempStackTop ? next_pos : tempStackTop;
        tempStack[tempStackTop + 1] = act;
        act = action.get(action_index++); // tAction(act, current_kind);
      }

      //
      // No error was detected, Read next token into
      // PREVTOK element, advance CURRENT_TOKEN pointer and
      // update stacks.
      //
      if (act != ERROR_ACTION) {
        prevStackTop = stateStackTop;
        for (var i = prev_pos + 1; i <= prevStackTop; i++) {
          prevStack[i] = stateStack[i];
        }
        prev_pos = pos;

        stateStackTop = nextStackTop;
        for (var k = pos + 1; k <= stateStackTop; k++) {
          stateStack[k] = nextStack[k];
        }
        locationStack[stateStackTop] = current_token;
        pos = next_pos;
      }
    }

    //
    // At this stage, either we have an ACCEPT or an ERROR
    // action.
    //
    if (act == ERROR_ACTION) {
      //
      // An error was detected.
      //
      errorCount += 1;

      //
      // Check time and error limits after the first error encountered
      // Exit if number of errors exceeds maxError or if maxTime reached
      //
      if (errorCount > 1) {
        if (maxErrors > 0 && errorCount > maxErrors) break;
        if (maxTime > 0 && currentTimeMillis() - startTime > maxTime) break;
      }

      var candidate = errorRecovery(current_token);

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

      act = stateStack[stateStackTop];

      //
      // If the recovery was successful on a nonterminal candidate,
      // parse through that candidate and "read" the next token.
      //
      if (candidate.symbol == 0) {
        break;
      } else if (candidate.symbol > NT_OFFSET) {
        var lhs_symbol = candidate.symbol - NT_OFFSET;
        act = ntAction(act, lhs_symbol);
        while (act <= NUM_RULES) {
          stateStackTop -= (rhs(act) - 1);
          act = ntAction(stateStack[stateStackTop], lhs(act));
        }
        stateStack[++stateStackTop] = act;
        current_token = tokStream.getToken();
        current_kind = tokStream.getKind(current_token);
        locationStack[stateStackTop] = current_token;
      } else {
        current_kind = candidate.symbol;
        locationStack[stateStackTop] = candidate.location;
      }

      //
      // At this stage, we have a recovery configuration. See how
      // far we can go with it.
      //
      var next_token = tokStream.peek();
      tempStackTop = stateStackTop;
      ArrayList.copy(stateStack, 0, tempStack, 0, stateStackTop + 1);
      error_token = parseForError(current_kind);

      //
      // If an error was found, compute the sequence of actions that reaches
      // the error token. Otherwise, claim victory...
      //
      if (error_token != 0) {
        tokStream.reset(next_token);
        tempStackTop = stateStackTop;
        ArrayList.copy(stateStack, 0, tempStack, 0, stateStackTop + 1);
        parseUpToError(action, current_kind, error_token);
        tokStream.reset(next_token);
      } else {
        act = ACCEPT_ACTION;
      }
    }
  } while (act != ACCEPT_ACTION);

  return;
}