[antlr-interest] how to parse a fraction

Sven Prevrhal sprevrha at gmail.com
Fri Sep 26 11:25:48 PDT 2008


Thanks Gavin, that worked ! - and I have another question! Here's my .g file
contents:

grammar fractest;

integer	:	INT;
fraction:	INT SLASH INT;
float	:	INT DOT INT;
word	:	~('\r' | '\n' | ' ' | '\t')+ ;

INT	:	'0'..'9'+;
SLASH 	:	'/';
DOT	:	'.';
WS 	:	(' ' | '\t')+ {$channel = HIDDEN;} ;

This above works. However, this below  where I replaced the word parser rule
with a WORD lexer token

integer	:	INT;
fraction:	INT SLASH INT;
float	:	INT DOT INT;

WORD	:	~('\r' | '\n' | ' ' | '\t')+ ;
INT	:	'0'..'9'+;
SLASH 	:	'/';
DOT	:	'.';
WS 	:	(' ' | '\t')+ {$channel = HIDDEN;} ;

does not work for fraction like 2/3 but it does work for 2 / 3 (with
spaces). Is it that when I define a word through the lexer it precedes the
fraction definition and grabs 2/3 as a WORD?

Second question:

If I define 

amount	:	integer
		| fraction
		| float
		;

with the first code block, rule 'amount' works for fractions and floats but
not for integers (no viable alt exception)! What is happening?

Thanks so much, greetings to NZ from SF, CA
Sven, extremely green noob

-----Original Message-----
From: Gavin Lambert [mailto:antlr at mirality.co.nz] 
Sent: Friday, September 26, 2008 12:43 AM
To: sven.prevrhal at ucsf.edu; antlr-interest at antlr.org
Subject: Re: [antlr-interest] how to parse a fraction

At 18:46 26/09/2008, Sven Prevrhal wrote:
>One like 1/2 ?
>INT '/' INT does not work as it requires spaces 
>between the numbers and the slash.

If you've defined your grammar in the standard 
way (and if the above is in a parser rule), it 
won't actually require spaces (but it won't 
object if they're there).

INT : ('0'..'9')+;
SLASH : '/';
WS : (' ' | '\t' | '\r' | '\n')+ { $channel = HIDDEN; };

fraction : INT SLASH INT;

The above should match "1/2", "1   /2", "1/   2", 
and "1     /    2" (among other combinations).

Now, if you explicitly want to *forbid* 
whitespace to appear in there, you'll have to 
match it entirely as a lexer rule:

fragment INT : ('0'..'9')+;
SLASH : '/';
FRACTION
   :  INT
      ( (SLASH) => SLASH INT
      | { $type = INT; }
      )
   ;
WS : (' ' | '\t' | '\r' | '\n')+ { $channel = HIDDEN; };

value : INT | FRACTION;

Of course, if you have a division operator then 
all of the above is probably redundant, since the 
fraction one-half is the result of treating "1/2" 
as a division expression (unless you're doing 
integer division, of course).




More information about the antlr-interest mailing list