[antlr-interest] how to parse a number and a unit

Sven Prevrhal sprevrha at gmail.com
Fri Sep 26 11:56:22 PDT 2008


I want to parse a number and a unit - with the code below 'ingline' can
parse 
5.2sm
But not 
5.2 sm
- why?

If I add a rule
space	:	(' ' | '\t')+;
and modify ingline to
ingline	:	float space? unit;
then both lines, with or without space. However, the 'space' now appears in
the parse tree. Now if I parse a  line with multiple spaces like so
5.2     sm
this works too BUT the 'space' no longer appears in the parse tree (I use
ANTLworks)!!!! I AM A BIG QUESTION MARK. And 
ingline	:	float WS? unit won't work at all.

Please enlighten me  - Sven

---- My GRAMMAR ----

grammar fractest;

ingline	:	float unit;

integer	:	INT;
fraction:	INT SLASH INT;
float	:	INT DOT INT;
word	:	~('\r' | '\n' | ' ' | '\t')+ ;
unit	:	'x ' | 'sm' | 'md' | 'lg' | 'cn' | 'pk' | 'pn' | 'dr' | 'ds'
               | 'ct' | 'bn' | 'sl' | 'ea' | 't ' | 'ts' | 'T ' | 'tb' |
'fl'
               | 'c ' | 'pt' | 'qt' | 'ga' | 'oz' | 'lb' | 'ml' | 'cb' |
'cl'
               | 'dl' | 'l ' | 'mg' | 'cg' | 'dg' | 'g ' | 'kg' | '  ';

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



-----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