[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