Пример #1
0
  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;
  }
Пример #2
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);
  }