private int panicRecover( ParseStack stack, Stack realStack, ITokenStream stream, ISyntaxErrorRequestor problemRequestor) { // Remember the first token int left = stream.getLookAhead().left; int right = stream.getLookAhead().right; // Dump the entire part stack.dumpStackUntil(NodeTypes.part, NodeTypes.RECORD); while (stack.getStackTop() != realStack.size() - 1) { realStack.pop(); } // Delete the input tokens until we can parse RECOVERY_SUCCESS tokens ahead while (true) { ParseStack trialStack = stack.createCopy(); if (trialStack.parseCheck(stream, RECOVERY_SUCCESS) == RECOVERY_SUCCESS) { break; } stream.advanceLookAhead(); } // Only report the panic error if we haven't reported too many already if (errorsDetected < MAX_ERRORS) { problemRequestor.panicPhrase(left, right); } // Panic recoveries do not create artificial nodes return 0; }
private int recover(Stack realStack, boolean[] isNonTerminal) { // Create a full parse stack for use during recovery ParseStack stack = new ParseStack(realStack, isNonTerminal); // Increment the error count errorsDetected++; // Only attempt sophisticated recovery if the file do not have too many errors already if (errorsDetected < MAX_ERRORS) { // Simple Recovery AbstractRecovery bestRecovery; AbstractRecovery[] recoveries = new AbstractRecovery[] { new ScopeRecovery(stack, realStack, stream, problemRequestor), new TerminalDeletionRecovery(stack, realStack, stream, problemRequestor), new NonTerminalSubstitutionRecovery(stack, realStack, stream, problemRequestor), new TerminalSubstitutionRecovery(stack, realStack, stream, problemRequestor), new NonTerminalInsertionRecovery(stack, realStack, stream, problemRequestor), new TerminalInsertionRecovery(stack, realStack, stream, problemRequestor), new PreviousTerminalDeletionRecovery(stack, realStack, stream, problemRequestor), new PreviousNonTerminalSubstitutionRecovery(stack, realStack, stream, problemRequestor), new PreviousTerminalSubstitutionRecovery(stack, realStack, stream, problemRequestor), new PreviousNonTerminalInsertionRecovery(stack, realStack, stream, problemRequestor), new PreviousTerminalInsertionRecovery(stack, realStack, stream, problemRequestor), }; bestRecovery = recoveries[0]; for (int i = 1; i < recoveries.length; i++) { if (recoveries[i].getParseCheckDistance() > bestRecovery.getParseCheckDistance()) { bestRecovery = recoveries[i]; } } if (bestRecovery.getParseCheckDistance() >= RECOVERY_SUCCESS) { int result = bestRecovery.performRecovery(); stack.sync(isNonTerminal); return result; } // Phrase Recovery AdvancedPhraseRecovery phraseRecovery = new AdvancedPhraseRecovery(stack, realStack, stream, problemRequestor); if (phraseRecovery.getParseCheckDistance() >= RECOVERY_SUCCESS) { if (phraseRecovery.getNumTokensDeleted() < RECOVERY_SUCCESS) { int result = phraseRecovery.performRecovery(); stack.sync(isNonTerminal); return result; } else { int result = bestRecovery.performRecovery(); stack.sync(isNonTerminal); return result; } } } // Output too many syntax error message when the limit is busted if (errorsDetected == MAX_ERRORS) { problemRequestor.tooManyErrors(); } // Panic Recovery return panicRecover(stack, realStack, stream, problemRequestor); }