Разбор ANTLR 3 - несоответствующий символ ... ожидающий - PullRequest
1 голос
/ 22 марта 2012

Я спокойный новичок в ANTLR и некоторое время оглядывался по сторонам, чтобы решить мою проблему. К сожалению, безуспешно ...

Я упростил свою грамматику для описания проблемы (в реальном примере используется токен TAG):


grammar Test;

WORD : ('a'..'z')+;

DOT : '.';

TAG : '.test';

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


rule
    :   'a' DOT WORD 'z';

Когда я пытаюсь разобрать слово "a .bcd z", все в порядке, но когда я пробую слово "a .tbyfa z", оно показывает мне ошибку

line 1:4 mismatched character 'b' expecting 'e'
line 1:5 missing DOT at 'yfa'

На мой взгляд, проблема в том, что строка после "." начинается с буквы "t", которая также может быть токеном ".test". Я попытался вернуться = true, но также безуспешно.


Как я могу решить эту проблему?
Заранее спасибо.

1 Ответ

2 голосов
/ 22 марта 2012

Лексер ANTLR не может вернуться к альтернативе в этом случае. Когда лексер видит ".t", он пытается сопоставить токен TAG, но это не удается, поэтому лексер затем пытается сопоставить что-то еще, начинающееся с ".t", но есть нет такого жетона. И лексер не вернет символ обратно, чтобы соответствовать DOT. Так вот что идет не так.

Возможное решение - это сделать так:

grammar Test;

rule  : 'a' DOT WORD 'z';
WORD  : ('a'..'z')+;
DOT   : '.' (('test')=> 'test' {$type=TAG;})?;
SPACE :  (' '|'\t'|'\n'|'\r')+ {$channel = HIDDEN;};

fragment TAG : /* empty rule: only used to change the 'type' */;

('test')=> - это синтаксический предикат, который заставляет лексера смотреть вперед, чтобы увидеть, действительно ли впереди "test". Если это правда, "test" соответствует, и тип токена изменяется на TAG. А поскольку 'test' является необязательным, правило всегда может использовать только токен DOT.

...