views:

51

answers:

1

I want to create a token from '..' in the ANTLR3 lexer which will be used to string together expressions like

a..b     // [1]
c .. x   // [2]
1..2     // [3] 
3 .. 4   // [4]

So, I have added,

DOTDOTSEP : '..' 
          ;

The problem is that I already have a rule:

FLOAT : INT (('.' INT (('e'|'E') INT)? 'f'?) | (('e'|'E') INT)? ('f'))
      ;

And in example [3] above 1..2 is getting matched as a FLOAT (I'm not sure why since following the first . is another . not an INT, but it is).

I wonder if there is a way to change the precedence of the lexer rules so DOTDOTSEP gets matched first and then FLOAT.

Looking here it seems I'm losing out to, "The rule having the greatest count is the winner.", but wonder if there is a way around it.

P.S. INT is defined as below ...

fragment DIGIT
    : '0'..'9'
    ;

INT : DIGIT+
    ;

Edit. A little further testing makes me think it's not quite as simple as it getting directly matched to the FLOAT rule. (I was going to change the question but since I've got answers now, I won't.) The problem (I believe) still lies in the lexer rules precedence so the question still remains the same.

+3  A: 

Did you look at http://sds.sourceforge.net/src/antlr/doc/lexer.html ?

A possible solution is to define the following:

fragment
INT : DIGIT+
    ;

fragment
RANGE : INT DOTDOTSEP INT
      ;

fragment
FLOAT : INT (('.' INT (('e'|'E') INT)? 'f'?) | (('e'|'E') INT)? ('f'))
      ;

NUMBER
    : (INT '.') => FLOAT       { $type=FLOAT; }
    | (INT DOTDOTSEP) => RANGE { $type=RANGE; }
    | INT                      { $type=INT; }
    ;
Marc
That's getting me much closer, just a little more tweaking needed. The link I hadn't found but it looks great; just the sort of thing I should be reading, so I'm off to do that now. Thanks.
tjm
I've got it going nicely now, just a couple of notes for anyone else that may come by this. In ANTLRWorks v1.4, the interpreter can't deal with predicates so it looks like there are errors when there aren't (that slowed me down a bit) and also I had to change `$settype(TYPE);` to `$type=TYPE;`
tjm
@tjm, I edited the ANTLR sample slightly. Is it now v3 compatible?
Bart Kiers
@Bart. I noticed your edits, thankyou they were helpful. As far as I can tell it **is** now v3 compatible. And at the very least I can definitely say, "well it works over here! (TM)" :)
tjm