Beispiel #1
0
void AntlrInput::lexerError(pANTLR3_BASE_RECOGNIZER recognizer) {
  pANTLR3_LEXER lexer = (pANTLR3_LEXER)(recognizer->super);
  assert(lexer!=NULL);
  Parser *parser = (Parser*)(lexer->super);
  assert(parser!=NULL);
  AntlrInput *input = (AntlrInput*) parser->getInput();
  assert(input!=NULL);

  /* Call the error display routine *if* there's not already a 
   * parse error pending.  If a parser error is pending, this
   * error is probably less important, so we just drop it. */
  if( input->d_parser->rec->state->error == ANTLR3_FALSE ) {
    input->parseError("Error finding next token.");
  }
}
Beispiel #2
0
/* *** CVC4 NOTE ***
 * This function is has been modified in not-completely-trivial ways from its
 * libantlr3c implementation to support more informative error messages and to
 * invoke the error reporting mechanism of the Input class instead of the
 * default error printer.
 */
void AntlrInput::reportError(pANTLR3_BASE_RECOGNIZER recognizer) {
    pANTLR3_EXCEPTION ex = recognizer->state->exception;
    pANTLR3_UINT8 * tokenNames = recognizer->state->tokenNames;
    stringstream ss;

    // Dig the CVC4 objects out of the ANTLR3 mess
    pANTLR3_PARSER antlr3Parser = (pANTLR3_PARSER)(recognizer->super);
    assert(antlr3Parser!=NULL);
    Parser *parser = (Parser*)(antlr3Parser->super);
    assert(parser!=NULL);
    AntlrInput *input = (AntlrInput*) parser->getInput() ;
    assert(input!=NULL);

    // Signal we are in error recovery now
    recognizer->state->errorRecovery = ANTLR3_TRUE;

    // Indicate this recognizer had an error while processing.
    recognizer->state->errorCount++;

    // Call the builtin error formatter
    // recognizer->displayRecognitionError(recognizer, recognizer->state->tokenNames);

    /* TODO: Make error messages more useful, maybe by including more expected tokens and information
     * about the current token. */
    switch(ex->type) {
    case ANTLR3_UNWANTED_TOKEN_EXCEPTION:

        // Indicates that the recognizer was fed a token which seems to be
        // spurious input. We can detect this when the token that follows
        // this unwanted token would normally be part of the syntactically
        // correct stream. Then we can see that the token we are looking at
        // is just something that should not be there and throw this exception.
        //
        if(tokenNames == NULL) {
            ss << "Unexpected token." ;
        } else {
            if(ex->expecting == ANTLR3_TOKEN_EOF) {
                ss << "Expected end of file.";
            } else {
                ss << "Expected " << tokenNames[ex->expecting]
                   << ", found '" << tokenText((pANTLR3_COMMON_TOKEN)ex->token) << "'.";
            }
        }
        break;

    case ANTLR3_MISSING_TOKEN_EXCEPTION:

        // Indicates that the recognizer detected that the token we just
        // hit would be valid syntactically if preceded by a particular
        // token. Perhaps a missing ';' at line end or a missing ',' in an
        // expression list, and such like.
        //
        if(tokenNames == NULL) {
            ss << "Missing token (" << ex->expecting << ").";
        } else {
            if(ex->expecting == ANTLR3_TOKEN_EOF) {
                ss << "Missing end of file marker.";
            } else if( ex->expecting == 0 ) {
                ss << "Unexpected token: '" << tokenText((pANTLR3_COMMON_TOKEN)ex->token) << "'.";
                if( std::string(tokenText((pANTLR3_COMMON_TOKEN)ex->token)) == std::string("IN") ) {
                    ss << " Did you mean: `IS_IN'?";
                }
            } else {
                ss << "Missing " << tokenNames[ex->expecting] << ".";
            }
        }
        break;

    case ANTLR3_RECOGNITION_EXCEPTION:

        // Indicates that the recognizer received a token
        // in the input that was not predicted. This is the basic exception type
        // from which all others are derived. So we assume it was a syntax error.
        // You may get this if there are not more tokens and more are needed
        // to complete a parse for instance.
        //
        ss <<"Syntax error.";
        break;

    case ANTLR3_MISMATCHED_TOKEN_EXCEPTION:

        // We were expecting to see one thing and got another. This is the
        // most common error if we could not detect a missing or unwanted token.
        // Here you can spend your efforts to
        // derive more useful error messages based on the expected
        // token set and the last token and so on. The error following
        // bitmaps do a good job of reducing the set that we were looking
        // for down to something small. Knowing what you are parsing may be
        // able to allow you to be even more specific about an error.
        //
        if(tokenNames == NULL) {
            ss << "Syntax error.";
        } else {
            if(ex->expecting == ANTLR3_TOKEN_EOF) {
                ss << "Expected end of file.";
            } else if( ex->expecting == 0 ) {
                ss << "Unexpected token: '" << tokenText((pANTLR3_COMMON_TOKEN)ex->token) << "'.";
            } else {
                ss << "Expected " << tokenNames[ex->expecting] << ".";
            }
        }
        break;

    case ANTLR3_NO_VIABLE_ALT_EXCEPTION:
        // We could not pick any alt decision from the input given
        // so god knows what happened - however when you examine your grammar,
        // you should. It means that at the point where the current token occurred
        // that the DFA indicates nowhere to go from here.
        //
        ss << "Unexpected token: '" << tokenText((pANTLR3_COMMON_TOKEN)ex->token) << "'.";
        break;

    case ANTLR3_MISMATCHED_SET_EXCEPTION:

    {
        ANTLR3_UINT32 count;
        ANTLR3_UINT32 bit;
        ANTLR3_UINT32 size;
        ANTLR3_UINT32 numbits;
        pANTLR3_BITSET errBits;

        // This means we were able to deal with one of a set of
        // possible tokens at this point, but we did not see any
        // member of that set.
        //
        ss << "Unexpected input: '" << tokenText((pANTLR3_COMMON_TOKEN)ex->token)
           << "'. Expected one of: ";

        // What tokens could we have accepted at this point in the
        // parse?
        //
        count = 0;
        errBits = antlr3BitsetLoad(ex->expectingSet);
        numbits = errBits->numBits(errBits);
        size = errBits->size(errBits);

        if(size > 0) {
            // However many tokens we could have dealt with here, it is usually
            // not useful to print ALL of the set here. I arbitrarily chose 8
            // here, but you should do whatever makes sense for you of course.
            // No token number 0, so look for bit 1 and on.
            //
            for(bit = 1; bit < numbits && count < 8 && count < size; bit++) {
                // TODO: This doesn;t look right - should be asking if the bit is set!!
                //
                if(tokenNames[bit]) {
                    if( count++ > 0 ) {
                        ss << ", ";
                    }
                    ss << tokenNames[bit];
                }
            }
        } else {
            assert(false);//("Parse error with empty set of expected tokens.");
        }
    }
    break;

    case ANTLR3_EARLY_EXIT_EXCEPTION:

        // We entered a loop requiring a number of token sequences
        // but found a token that ended that sequence earlier than
        // we should have done.
        //
        ss << "Sequence terminated early by token: '"
           << tokenText((pANTLR3_COMMON_TOKEN)ex->token) << "'.";
        break;

    default:

        // We don't handle any other exceptions here, but you can
        // if you wish. If we get an exception that hits this point
        // then we are just going to report what we know about the
        // token.
        //
        assert(false);//("Unexpected exception in parser.");
        break;
    }

    // Call the error display routine
    input->parseError(ss.str(), ((pANTLR3_COMMON_TOKEN)ex->token)->type == ANTLR3_TOKEN_EOF);
}