[antlr-interest] Different logic generated by antlr 3 and antlr 2

Hub Dog hubdog at gmail.com
Sun Sep 23 06:30:55 PDT 2007


Dear friends,

        I just porting an antlr 2 project to antlr3 . But I just encounter
problem.
for the following rule

sql_script :
    (sql_stmt)? ( SEMI! (sql_stmt)? )*
;


Antlr2 will generate following source(C++ Target), it will throw exception
when encounter incorrect input after the correct sub rule:
....
    {
    if ((_tokenSet_0.member(LA(1)))) {
        sql_stmt();
        if (inputState->guessing==0) {
            astFactory->addASTChild( currentAST, returnAST );
        }
    }
    else if ((LA(1) == Token::EOF_TYPE || LA(1) == SEMI)) {
    }
    else {
        throw NoViableAltException(LT(1), getFilename());<-----------Throw
exception when encounter incorrect input after correct sql.
    }

    }
    { // ( ... )*
    for (;;) {
        if ((LA(1) == SEMI)) {
            semi = LT(1);
            if ( inputState->guessing == 0 ) {
                semi_AST = astFactory->create(semi);
            }
            match(SEMI);
            {
            if ((_tokenSet_0.member(LA(1)))) {
                sql_stmt();
                if (inputState->guessing==0) {
                    astFactory->addASTChild( currentAST, returnAST );
                }
            }
            else if ((LA(1) == Token::EOF_TYPE || LA(1) == SEMI)) {
            }
            else {
                throw NoViableAltException(LT(1),
getFilename());<-----------Throw exception when encounter incorrect input
after correct sql.
            }

            }
        }
        else {
            goto _loop90;
        }

    }
    _loop90:;
    } // ( ... )*

So my parser will report error for the statement  : drop table a select.(the
drop table a is correct sql but select is wrong)

But Antlr3 will generate quit different source(Java target), it will not
throw exception for the pattern that a wrong input just following a correct
sub rule

            int LA1_0 = input.LA(1);

            if ( ((LA1_0>=T_DELETE &&
LA1_0<=T_INSERT)||LA1_0==T_SELECT||LA1_0==T_EXPLAIN||LA1_0==T_REPLACE||(LA1_0>=T_REINDEX
&&
LA1_0<=T_ATTACH)||LA1_0==T_DETACH||LA1_0==T_CREATE||LA1_0==T_END||LA1_0==T_BEGIN||LA1_0==T_ROLLBACK||(LA1_0>=T_PRAGMA
&& LA1_0<=T_ALTER)||LA1_0==T_COMMIT) ) {
                alt1=1;
            }
            switch (alt1) {
                case 1 :
                    // Sqlite.g:389:3: sql_stmt
                    {
                    pushFollow(FOLLOW_sql_stmt_in_sql_script1621);
                    sql_stmt1=sql_stmt();
                    _fsp--;
                    if (failed) return retval;
                    if ( backtracking==0 ) adaptor.addChild(root_0,
sql_stmt1.getTree());

                    }
                    break;

            }

            // Sqlite.g:389:14: ( SEMI ( sql_stmt )? )*
            loop3:
            do {
                int alt3=2;
                int LA3_0 = input.LA(1);

                if ( (LA3_0==SEMI) ) {
                    alt3=1;
                }


                switch (alt3) {
                case 1 :
                    // Sqlite.g:389:16: SEMI ( sql_stmt )?
                    {
                    SEMI2=(Token)input.LT(1);
                    match(input,SEMI,FOLLOW_SEMI_in_sql_script1627); if
(failed) return retval;
                    // Sqlite.g:389:22: ( sql_stmt )?
                    int alt2=2;
                    int LA2_0 = input.LA(1);

                    if ( ((LA2_0>=T_DELETE &&
LA2_0<=T_INSERT)||LA2_0==T_SELECT||LA2_0==T_EXPLAIN||LA2_0==T_REPLACE||(LA2_0>=T_REINDEX
&&
LA2_0<=T_ATTACH)||LA2_0==T_DETACH||LA2_0==T_CREATE||LA2_0==T_END||LA2_0==T_BEGIN||LA2_0==T_ROLLBACK||(LA2_0>=T_PRAGMA
&& LA2_0<=T_ALTER)||LA2_0==T_COMMIT) ) {
                        alt2=1;
                    }
                    switch (alt2) {
                        case 1 :
                            // Sqlite.g:389:23: sql_stmt
                            {
                            pushFollow(FOLLOW_sql_stmt_in_sql_script1631);
                            sql_stmt3=sql_stmt();
                            _fsp--;
                            if (failed) return retval;
                            if ( backtracking==0 ) adaptor.addChild(root_0,
sql_stmt3.getTree());

                            }
                            break;

                    }


                    }
                    break;

                default :
                    break loop3;<----------------------------does not throw
exception for input other than SEMI
                }
            } while (true);


            }

My question is how to let antlr3 to generate the same logic like antlr 2.

best regards
ma lifang
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.antlr.org/pipermail/antlr-interest/attachments/20070923/1c88bd93/attachment-0001.html 


More information about the antlr-interest mailing list