scopeTrialCheck method

void scopeTrialCheck(
  1. PrimaryRepairInfo repair,
  2. List<int> stack,
  3. int stack_top,
  4. int indx,
)

Implementation

void scopeTrialCheck(
    PrimaryRepairInfo repair, List<int> stack, int stack_top, int indx) {
  StateInfo? info;
  for (var i = stateSeen[stack_top]; i != NIL; i = info.next) {
    info = statePool[i];
    if (null == info) {
      break;
    }

    if (info.state == stack[stack_top]) return;
  }

  var old_state_pool_top = statePoolTop++;
  if (statePoolTop >= statePool.length) {
    ArrayList.copy(statePool, 0,
        statePool = List.filled(statePoolTop * 2, null), 0, statePoolTop);
  }

  statePool[old_state_pool_top] =
      StateInfo(stack[stack_top], stateSeen[stack_top]);
  stateSeen[stack_top] = old_state_pool_top;

  var action = IntTuple(1 << 3);
  for (var i = 0; i < SCOPE_SIZE; i++) {
    //
    // Compute the action (or set of actions in case of conflicts) that
    // can be executed on the scope lookahead symbol. Save the action(s)
    // in the action tuple.
    //
    action.reset();
    var act = tAction(stack[stack_top], scopeLa(i));
    if (act > ACCEPT_ACTION && act < ERROR_ACTION) // conflicting actions?
    {
      do {
        action.add(baseAction(act++));
      } while (baseAction(act) != 0);
    } else {
      action.add(act);
    }

    //
    // For each action defined on the scope lookahead symbol,
    // try scope recovery.
    //
    for (var action_index = 0; action_index < action.size(); action_index++) {
      tokStream.reset(buffer[repair.bufferPosition]);
      tempStackTop = stack_top - 1;
      var max_pos = stack_top;

      act = action.get(action_index);
      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 > max_pos
              ? tempStack[tempStackTop]
              : stack[tempStackTop]);
          act = ntAction(act, lhs_symbol);
        } while (act <= NUM_RULES);
        if (tempStackTop + 1 >= stateStack.length) return;
        max_pos = max_pos < tempStackTop ? max_pos : tempStackTop;
        tempStack[tempStackTop + 1] = act;
        act = tAction(act, scopeLa(i));
      }

      //
      // If the lookahead symbol is parsable, then we check
      // whether or not we have a match between the scope
      // prefix and the transition symbols corresponding to
      // the states on top of the stack.
      //
      if (act != ERROR_ACTION) {
        int j, k = scopePrefix(i);
        for (j = tempStackTop + 1;
            j >= (max_pos + 1) && inSymbol(tempStack[j]) == scopeRhs(k);
            j--) {
          k++;
        }

        if (j == max_pos) {
          for (j = max_pos;
              j >= 1 && inSymbol(stack[j]) == scopeRhs(k);
              j--) {
            k++;
          }
        }
        //
        // If the prefix matches, check whether the state
        // newly exposed on top of the stack, (after the
        // corresponding prefix states are popped from the
        // stack), is in the set of "source states" for the
        // scope in question and that it is at a position
        // below the threshold indicated by MARKED_POS.
        //
        var marked_pos = (max_pos < stack_top ? max_pos + 1 : stack_top);
        if (scopeRhs(k) == 0 && j < marked_pos) // match?
        {
          var stack_position = j;
          for (j = scopeStateSet(i);
              stack[stack_position] != scopeState(j) && scopeState(j) != 0;
              j++) {
            ;
          }
          //
          // If the top state is valid for scope recovery,
          // the left-hand side of the scope is used as
          // starting symbol and we calculate how far the
          // parser can advance within the forward context
          // after parsing the left-hand symbol.
          //
          if (scopeState(j) != 0) // state was found
          {
            var previous_distance = repair.distance,
                distance = parseCheck(stack, stack_position,
                    scopeLhs(i) + NT_OFFSET, repair.bufferPosition);
            //
            // if the recovery is not successful, we
            // update the stack with all actions induced
            // by the left-hand symbol, and recursively
            // call SCOPE_TRIAL_CHECK to try again.
            // Otherwise, the recovery is successful. If
            // the new distance is greater than the
            // initial SCOPE_DISTANCE, we update
            // SCOPE_DISTANCE and set scope_stack_top to INDX
            // to indicate the number of scopes that are
            // to be applied for a succesful  recovery.
            // NOTE that this procedure cannot get into
            // an infinite loop, since each prefix match
            // is guaranteed to take us to a lower point
            // within the stack.
            //
            if ((distance - repair.bufferPosition + 1) < MIN_DISTANCE) {
              var top = stack_position;
              act = ntAction(stack[top], scopeLhs(i));
              while (act <= NUM_RULES) {
                top -= (rhs(act) - 1);
                act = ntAction(stack[top], lhs(act));
              }
              top++;

              j = act;
              act = stack[top]; // save
              stack[top] = j; // swap
              scopeTrialCheck(repair, stack, top, indx + 1);
              stack[top] = act; // restore
            } else if (distance > repair.distance) {
              scopeStackTop = indx;
              repair.distance = distance;
            }

            //
            // If no other recovery possibility is left (due to
            // backtracking and we are at the end of the input,
            // then we favor a scope recovery over all other kinds
            // of recovery.
            //
            if ( // TODO: main_configuration_stack.size() == 0 && // no other bactracking possibilities left
                tokStream.getKind(buffer[repair.bufferPosition]) ==
                        EOFT_SYMBOL &&
                    repair.distance == previous_distance) {
              scopeStackTop = indx;
              repair.distance = MAX_DISTANCE;
            }

            //
            // If this scope recovery has beaten the
            // previous distance, then we have found a
            // better recovery (or this recovery is one
            // of a list of scope recoveries). Record
            // its information at the proper location
            // (INDX) in SCOPE_INDEX and SCOPE_STACK.
            //
            if (repair.distance > previous_distance) {
              scopeIndex[indx] = i;
              scopePosition[indx] = stack_position;
              return;
            }
          }
        }
      }
    }
  }
}