[antlr-interest] Trouble with syntactic predicates for parenthesized expressions

Vaclav Barta vbar at comp.cz
Fri Jul 6 12:10:09 PDT 2007


Hi,

continuing with my SQL experiments, should the grammar below (again, 
ported from 
http://www.antlr.org/grammar/1062280680642/MS_SQL_SELECT.html and 
simplified to demonstrate a point) parse "(a = b)" (without the quotes, 
obviously)?

grammar Detail;

options
{
	language=CSharp;
}

@lexer::namespace
{
	Detail
}

@parser::namespace
{
	Detail
}

@rulecatch {
}

searchCondition:
	subSearchCondition ( (AND | OR) subSearchCondition )*
	;

subSearchCondition:
	(LPAREN searchCondition RPAREN) =>
		LPAREN searchCondition RPAREN
	| predicate
	;

predicate:
	expression comparisonOperator expression
	;

expression:
	subExpression (binaryOperator subExpression)*
  	;

subExpression:
	( unaryOperator )? (
		LPAREN expression RPAREN
		| dbObject
		| caseFunction
	)
	;

caseFunction:
	CASE ( expression ( WHEN expression THEN expression )+
         | ( WHEN searchCondition THEN expression )+ )
		( ELSE expression )? END
	;

dbObject:
	identifier
	( DOT identifier )*
	;

identifier:
	NonQuotedIdentifier
	;

unaryOperator:
	PLUS
	| MINUS
	| TILDE
	;

binaryOperator:
     PLUS | MINUS | STAR | DIVIDE | MOD
     ;

comparisonOperator:
	ASSIGNEQUAL | NOTEQUAL1 | NOTEQUAL2 | LESSTHANOREQUALTO1
	| LESSTHANOREQUALTO2 | LESSTHAN | GREATERTHANOREQUALTO1
	| GREATERTHANOREQUALTO2 | GREATERTHAN
	;

AND : 'and' ;
CASE : 'case' ;
ELSE : 'else' ;
END : 'end' ;
NOT : 'not' ;
OR : 'or' ;
THEN : 'then' ;
WHEN : 'when' ;

DOT : '.' ;
COMMA : ',' ;
LPAREN : '(' ;
RPAREN : ')' ;

ASSIGNEQUAL : '=' ;
NOTEQUAL1 : '<>' ;
NOTEQUAL2 : '!=' ;
LESSTHANOREQUALTO1 : '<=' ;
LESSTHANOREQUALTO2 : '!>' ;
LESSTHAN : '<' ;
GREATERTHANOREQUALTO1 : '>=' ;
GREATERTHANOREQUALTO2 : '!<' ;
GREATERTHAN : '>' ;

DIVIDE : '/' ;
PLUS : '+' ;
MINUS : '-' ;
STAR : '*' ;
MOD : '%' ;

TILDE : '~' ;

fragment
Letter : 'a'..'z' | '_' ;

fragment
Digit : '0'..'9' ;

Whitespace : ( '\t' | ' ' | '\r' | '\n' )+ 	{ $channel = HIDDEN; }
	;

NonQuotedIdentifier : Letter (Letter | Digit)* ;

I think it should - but ANTLR disagrees... :-( antlrworks-1.0.2 
generates the C# lexer & parser without warnings, the generated files 
compile cleanly, but

             DetailLexer lexer = new DetailLexer(
                 new ANTLRStringStream(text));
             DetailParser parser = new DetailParser(new 	
		CommonTokenStream(lexer));
             parser.searchCondition();

fails with

NoViableAltException(21!=[25:1: subSearchCondition : ( ( LPAREN 
searchCondition RPAREN )=> LPAREN searchCondition RPAREN | predicate );])

It isn't an isolated problem. It happens in lots of SQL expression 
grammar variants I've tried to write, appearing and going away after the 
most random (to me) changes - for example removing the caseFunction 
alternative from subExpression in the grammar above makes "(a = b)" 
parse OK, using an extra rule instead of LPAREN expr RPAREN generally 
improves results etc. Is it a bug in ANTLR?

	Bye
		Vasek




More information about the antlr-interest mailing list