[antlr-interest] Parsing floats and unary minus

Rick Mann rmann at latencyzero.com
Fri Apr 23 19:25:01 PDT 2010


I'm trying to write a simple time interval expression parser. I want to be able to write expressions like this:

	-15/2:03:45.3 + +02:43

where

	-	15	/	2	:	03	:	45.3
	negate	days		hours		minutes		seconds

I've appended my grammar below. It was working pretty well until I tried to introduce the floating-point literals in the seconds position. I tried changing s=int to s=float. What I really want is for it to be either a float or an int. But I don't want floats anywhere else.

"s=float" interprets in ANTLRWorks to "<epsilon>", and the grammar check gets some errors for "TimeInterval.g:11:4: The following alternatives can never be matched: 2" (the first line of the interval production).

I've spent an half-hour Googling, and while I find some discussion of unary minus, it's not clear to me what I need to do make it work in my situation. I also don't know what the epsilon stuff is all about.

Any feedback would be much appreciated. Thanks!

-- 
Rick




grammar TimeInterval;

intervalExpr returns [float val]
	:	i=interval { $val = $i.val; }
	(	'+' i=interval { $val += $i.val; }
	|	'-' i=interval { $val -= $i.val; }
	)*
	;
	
interval returns [float val]
	:	( '+'? i=posInterval { $val = $i.val; }
		| '-' i=posInterval { $val = -$i.val; }
		)
		;
		
posInterval returns [float val]
	:	(d=int '/')? (h=int ':')? (m=int ':')? s=int { $val = d * 24.0 * 3600.0 + h * 3600.0 + m * 60.0 + s; }
	;
	
int returns [float val]
	:	INT { $val = Integer.parseInt($INT.text); }
	;

float returns [float val]
	:	{ $val = Float.parseFloat($FLOAT.text); }
	;
	
INT :	'0'..'9'+
    ;

FLOAT
    :   ('0'..'9')+ '.' ('0'..'9')* EXPONENT?
    |   '.' ('0'..'9')+ EXPONENT?
    |   ('0'..'9')+ EXPONENT
    ;

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

fragment
EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;




More information about the antlr-interest mailing list