Пример #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;
  }
Пример #2
0
  private int errorRepair(int recovery_token, int error_token) {
    int temp_stack[] = new int[state.stateStackTop + 1];
    System.arraycopy(state.stateStack, 0, temp_stack, 0, temp_stack.length);
    for (;
        tokStream.getKind(recovery_token) != EOFT_SYMBOL;
        recovery_token = tokStream.getNext(recovery_token)) {
      System.out.println("recovery token: " + tokStream.getKind(recovery_token)); // $NON-NLS-1$
      tokStream.reset(recovery_token);
      if (repairable(error_token)) break;
      state.stateStackTop = temp_stack.length - 1;
      System.arraycopy(temp_stack, 0, state.stateStack, 0, temp_stack.length);
    }

    if (tokStream.getKind(recovery_token) == EOFT_SYMBOL) {
      tokStream.reset(recovery_token);
      if (!repairable(error_token)) {
        state.stateStackTop = temp_stack.length - 1;
        System.arraycopy(temp_stack, 0, state.stateStack, 0, temp_stack.length);
        return 0;
      }
    }

    state.stateStackTop = temp_stack.length - 1;
    System.arraycopy(temp_stack, 0, state.stateStack, 0, temp_stack.length);

    undoActions(state.undoStack[state.stateStackTop]);
    tokStream.reset(recovery_token);
    state.tokens.reset(state.locationStack[state.stateStackTop] - 1);
    state.actionCount = state.actionStack[state.stateStackTop];
    state.trialActionCount = state.undoStack[state.stateStackTop];

    return tokStream.makeErrorToken(
        state.tokens.get(state.locationStack[state.stateStackTop] - 1),
        tokStream.getPrevious(recovery_token),
        error_token,
        ERROR_SYMBOL);
  }