[antlr-interest] Fwd: changing the language ofdefault error handler for c++ parser

Peter Sprenger sprenger at moving-bytes.de
Fri Sep 17 05:07:41 PDT 2004


Hello,

I recently had the task to generate syntax errors in a foreign
language (german) in a ANTLR parser. Since the default error handling
is ok, I do not wanted to write an exception handler for every rule by
myself, I decided to change the default output only. Also I don't
wanted to change the C++ runtime library. Then my Odyssey began. To
override reportError() was easy. But a RecognitionException has not
all information necessary in the base class. So we have to distinguish
MismatchedTokenException and NoViableAltException via RTTI. Some data
like MismatchedTokenException::tokenName is not accessible, but can be
modified to use LLkParser::tokenNames of the generated parser. Also
the definitions of (TOKEN, NOT_TOKEN..etc) are only available in the
MismatchedTokenException class and had to be put manually in the code.

My code is working now, but it is not simple to understand why it had
to be written in that way and it is error prone to the slightest
change in the runtime library.
My question is, did I miss something? Or is there no easier way to
change the output of the default error handler? Perhaps the overall
scheme should be changed to ease such a task.

Best Regards,

Peter Sprenger


------ my sample code to change the output of the default handler ---

static const int TOKEN = 1;
static const int NOT_TOKEN = 2;
static const int RANGE = 3;
static const int NOT_RANGE = 4;
static const int SET = 5;
static const int NOT_SET = 6;
/** Parser error-reporting function can be overridden in subclass */
void CC_Parser::reportError(const ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex)
{
    ANTLR_USE_NAMESPACE(std)string err,tname,tnupper;
    ANTLR_USE_NAMESPACE(antlr)MismatchedTokenException *mtex;
    ANTLR_USE_NAMESPACE(antlr)NoViableAltException *naex;
    int i;
    
    if(typeid(ex)==typeid(ANTLR_USE_NAMESPACE(antlr)MismatchedTokenException))
    {
        mtex=(ANTLR_USE_NAMESPACE(antlr)MismatchedTokenException*)&ex;
        
        switch (mtex->mismatchType)
        {
            case TOKEN:
                tname=tokenNames[mtex->expecting];
                err= "expecting " + tname + ", found '" + mtex->tokenText + "'";
            break;
            case NOT_TOKEN:
                tname=tokenNames[mtex->expecting];
                err= "expecting anything but " + tname + "; got it anyway";
            break;
            case RANGE:
                tname=tokenNames[mtex->expecting];
                tnupper=tokenNames[mtex->upper];   
                err= "expecting token in range: " + tname + ".." + tnupper + ", found '" + mtex->tokenText + "'";
            break;
            case NOT_RANGE:
                tname=tokenNames[mtex->expecting];
                tnupper=tokenNames[mtex->upper];   
                err= "expecting token NOT in range: " + tname + ".." + tnupper + ", found '" + mtex->tokenText + "'";
            break;
            case SET:
            case NOT_SET:
                {
                    err= ANTLR_USE_NAMESPACE(std)string("expecting ") + (mtex->mismatchType == NOT_SET ? "NOT " : "") + "one of (";
                    ANTLR_USE_NAMESPACE(std)vector<unsigned int> elems = mtex->set.toArray();
                    for ( unsigned int i = 0; i < elems.size(); i++ )
                    {
                        tname=tokenNames[elems[i]];
                        err += " "+tname;
                    }
                    err += "), found '" + mtex->tokenText + "'";
                }
            break;
        }
    }
    
    if(typeid(ex)==typeid(ANTLR_USE_NAMESPACE(antlr)NoViableAltException))
    {
        naex=(ANTLR_USE_NAMESPACE(antlr)NoViableAltException*)&ex;
        
        if (naex->token)      
        {
            if(naex->token->getType() == ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE) err="unexpected end of file";
            else 
            if(naex->token->getType() == ANTLR_USE_NAMESPACE(antlr)Token::NULL_TREE_LOOKAHEAD ) err="unexpected end of tree";
            else
            err="unexpected token: "+naex->token->getText();
        }

        // must a tree parser error if token==null
        if (!naex->node) err="unexpected end of subtree";

    }
    
    printf("generic %d %d %s - ",ex.getLine(),ex.getColumn(),ex.getFilename().c_str());
    printf("%s\n",err.c_str());
    fflush(stdout);
    // original output
        ANTLR_USE_NAMESPACE(std)cerr << ex.toString().c_str() << ANTLR_USE_NAMESPACE(std)endl;
}


- 

------------------

Peter Sprenger
Moving Bytes Communications, Systementwicklung GmbH
Eisenstr.1
D-50825 Koeln
Germany

Tel.: +49/221/4923555
Fax.: +49/221/4923556
Email: sprenger at moving-bytes.de
http://www.moving-bytes.de






 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/antlr-interest/

<*> To unsubscribe from this group, send an email to:
    antlr-interest-unsubscribe at yahoogroups.com

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
 



More information about the antlr-interest mailing list