parseCheck method

int parseCheck(
  1. List<int> stack,
  2. int stack_top,
  3. int first_symbol,
  4. int buffer_position,
)

Implementation

int parseCheck(
    List<int> stack, int stack_top, int first_symbol, int buffer_position) {
  int buffer_index, current_kind;

  var local_stack = List<int>.filled(stack.length, 0);
  var local_stack_top = stack_top;
  for (var i = 0; i <= stack_top; i++) {
    local_stack[i] = stack[i];
  }

  var configuration_stack = ConfigurationStack(prs);

  //
  // If the first symbol is a nonterminal, process it here.
  //
  var act = local_stack[local_stack_top];
  if (first_symbol > NT_OFFSET) {
    var lhs_symbol = first_symbol - NT_OFFSET;
    buffer_index = buffer_position;
    current_kind = tokStream.getKind(buffer[buffer_index]);
    tokStream.reset(tokStream.getNext(buffer[buffer_index]));
    act = ntAction(act, lhs_symbol);
    while (act <= NUM_RULES) {
      local_stack_top -= (rhs(act) - 1);
      act = ntAction(local_stack[local_stack_top], lhs(act));
    }
  } else {
    local_stack_top--;
    buffer_index = buffer_position - 1;
    current_kind = first_symbol;
    tokStream.reset(buffer[buffer_position]);
  }

  //
  // Start parsing the remaining symbols in the buffer
  //
  if (++local_stack_top >= local_stack.length) {
    return buffer_index;
  }
  local_stack[local_stack_top] = act;

  act = tAction(act, current_kind);

  for (;;) {
    if (act <= NUM_RULES) // reduce action
    {
      local_stack_top -= rhs(act);
      act = ntAction(local_stack[local_stack_top], lhs(act));

      while (act <= NUM_RULES) {
        local_stack_top -= (rhs(act) - 1);
        act = ntAction(local_stack[local_stack_top], lhs(act));
      }
    } else if (act > ERROR_ACTION) // shift-reduce action
    {
      if (buffer_index++ == MAX_DISTANCE) break;
      current_kind = tokStream.getKind(buffer[buffer_index]);
      tokStream.reset(tokStream.getNext(buffer[buffer_index]));
      act -= ERROR_ACTION;

      do {
        local_stack_top -= (rhs(act) - 1);
        act = ntAction(local_stack[local_stack_top], lhs(act));
      } while (act <= NUM_RULES);
    } else if (act < ACCEPT_ACTION) // shift action
    {
      if (buffer_index++ == MAX_DISTANCE) break;
      current_kind = tokStream.getKind(buffer[buffer_index]);
      tokStream.reset(tokStream.getNext(buffer[buffer_index]));
    } else if (act == ERROR_ACTION) {
      var configuration = configuration_stack.pop();
      if (configuration == null) {
        act = ERROR_ACTION;
      } else {
        local_stack_top = configuration.stack_top;
        configuration.retrieveStack(local_stack);
        act = configuration.act;
        buffer_index = configuration.curtok;
        // no need to execute: action.reset(configuration.action_length);
        current_kind = tokStream.getKind(buffer[buffer_index]);
        tokStream.reset(tokStream.getNext(buffer[buffer_index]));
        continue;
      }
      break;
    } else if (act > ACCEPT_ACTION) {
      if (configuration_stack.findConfiguration(
          local_stack, local_stack_top, buffer_index)) {
        act = ERROR_ACTION;
      } else {
        configuration_stack.push(
            local_stack, local_stack_top, act + 1, buffer_index, 0);
        act = baseAction(act);
      }
      continue;
    } else {
      break;
    }

    if (++local_stack_top >= local_stack.length) {
      break; // Stack overflow!!!
    }
    local_stack[local_stack_top] = act;

    act = tAction(act, current_kind);
  }

  return (act == ACCEPT_ACTION ? MAX_DISTANCE : buffer_index);
}