Приоритет лексера ANTLR3 - PullRequest
       45

Приоритет лексера ANTLR3

5 голосов
/ 15 октября 2010

Я хочу создать токен из '..' в лексере ANTLR3, который будет использоваться для объединения воедино таких выражений, как

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

Итак, я добавил,

DOTDOTSEP : '..' 
          ;

Проблема в том, что у меня уже есть правило:

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

И в примере [3] выше 1..2 сопоставляется как FLOAT (я не уверен почему, так как после первого . это еще один . не INT, но это так.)

Интересно, есть ли способ изменить приоритет правил лексера, чтобы сначала сопоставить DOTDOTSEP, а затем FLOAT.

Глядя здесь кажется, что я проигрываю, "The rule having the greatest count is the winner.",, но задаюсь вопросом, есть ли способ обойти это.

PS INT определяется следующим образом ...

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

INT : DIGIT+
    ;

Редактировать. Небольшое дальнейшее тестирование заставляет меня думать, что это не так просто, как напрямую соответствовать правилу FLOAT.(Я собирался изменить вопрос, но так как у меня теперь есть ответы, я не буду.) Проблема (я полагаю) по-прежнему заключается в приоритете правил лексера, поэтому вопрос остается прежним.

1 Ответ

7 голосов
/ 15 октября 2010

Вы смотрели на http://sds.sourceforge.net/src/antlr/doc/lexer.html?

Возможным решением является определение следующего:

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; }
    ;
...