Exemplo n.º 1
0
  //
  // Parse input allowing up to max_error_count Error token recoveries.
  // When max_error_count is 0, no Error token recoveries occur.
  // When max_error is > 0, it limits the number of Error token recoveries.
  // When max_error is < 0, the number of error token recoveries is unlimited.
  // Also, such recoveries only require one token to be parsed beyond the
  // recovery point.
  // (normally two tokens beyond the recovery point must be parsed)
  // Thus, a negative max_error_count should be used when error productions
  // are used to
  // skip tokens.
  //
  public Object parse(int max_error_count) throws BadParseException {
    state = new ParserState(START_STATE, tokStream);
    skipTokens = max_error_count < 0;

    state.pendingCommits = new LinkedList();
    backtrackRequested = false;
    state.trialActionCount = 0;

    // Next "start" token
    state.repair_token = 0;

    int start_token_index = tokStream.peek();
    int start_action_index = 0;

    // Last commit point
    int[] temp_stack = new int[1];
    temp_stack[0] = START_STATE;

    state.reallocateOtherStacks(start_token_index);

    int initial_error_token = backtrackParse(state.repair_token);
    for (int error_token = initial_error_token, count = 0;
        error_token != 0;
        error_token = backtrackParse(state.repair_token), count++) {
      if (count == max_error_count) throw new BadParseException(initial_error_token);
      state.actionCount = start_action_index;
      tokStream.reset(start_token_index);
      state.stateStackTop = temp_stack.length - 1;
      System.arraycopy(temp_stack, 0, state.stateStack, 0, temp_stack.length);
      state.reallocateOtherStacks(start_token_index);

      backtrackParseUpToError(state.repair_token, error_token);

      for (state.stateStackTop = findRecoveryStateIndex(state.stateStackTop);
          state.stateStackTop >= 0;
          state.stateStackTop = findRecoveryStateIndex(state.stateStackTop - 1)) {
        int recovery_token = state.tokens.get(state.locationStack[state.stateStackTop] - 1);
        state.repair_token =
            errorRepair(
                (recovery_token >= start_token_index ? recovery_token : error_token), error_token);
        if (state.repair_token != 0) break;
      }

      if (state.stateStackTop < 0) throw new BadParseException(initial_error_token);

      temp_stack = new int[state.stateStackTop + 1];
      System.arraycopy(state.stateStack, 0, temp_stack, 0, temp_stack.length);

      start_action_index = state.actionCount;
      start_token_index = tokStream.peek();
    }

    if (state.repair_token != 0) state.tokens.add(state.repair_token);
    int t;
    for (t = start_token_index; tokStream.getKind(t) != EOFT_SYMBOL; t = tokStream.getNext(t))
      state.tokens.add(t);
    state.tokens.add(t);

    return null;
  }