// // 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; }
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); }