Семантический предикат лексера antlr об альтернативе

Учитывая грамматику:

grammar Test;
words: (WORD|SPACE|DOT)+;
WORD : (
       LD
       |DOT       {_input.LA(1)!='.'}?
       ) +        ;
DOT: '.';
SPACE: ' ';
fragment LD: ~[.\n\r ];

с лексером, сгенерированным Antlr4, для ввода:

test. test.test test..test

Последовательность токенов такая:

[@0,0:4='test.',<1>,1:0]
[@1,5:5=' ',<3>,1:5]
[@2,6:14='test.test',<1>,1:6]
[@3,15:15=' ',<3>,1:15]
[@4,16:19='test',<1>,1:16]
[@5,20:20='.',<2>,1:20]
[@6,21:25='.test',<1>,1:21]
[@7,26:25='<EOF>',<-1>,1:26]

Что озадачивает, почему последний фрагмент текста test..test токенизируется на test . и .test, в то время как я должен был видеть test. .test

Что меня больше озадачило, так это ввод:

test..test test. test.test

последовательность токенов:

[@0,0:3='test',<1>,1:0]
[@1,4:4='.',<2>,1:4]
[@2,5:9='.test',<1>,1:5]
[@3,10:10=' ',<3>,1:10]
[@4,11:14='test',<1>,1:11]
[@5,15:15='.',<1>,1:15]
[@6,16:16=' ',<3>,1:16]
[@7,17:20='test',<1>,1:17]
[@8,21:25='.test',<1>,1:21]
[@9,26:25='<EOF>',<-1>,1:26]

Здесь test.test разделен на два жетона, а наверху - один. Есть ли побочный эффект при вызове _input.LA (1)? Кто-нибудь может объяснить?

Пользуюсь Antlr4.


person Wudong    schedule 09.10.2013    source источник
comment
Я прав, что вы хотите игнорировать double DOT в своем WORD правиле лексера?   -  person Cv4    schedule 10.10.2013
comment
да. это на самом деле из моего другого вопроса: stackoverflow .com / questions / 19224181 / Я формализовал основную проблему для этого вопроса, надеясь прояснить ее.   -  person Wudong    schedule 10.10.2013


Ответы (1)


Быстрое исправление состоит в том, чтобы проверить предыдущий LA(-1) токен, если он не равен ., и добавить начальный необязательный DOT.

Полученная грамматика:

grammar Test;
words: (WORD|SPACE|DOT)+;
WORD : DOT? (
       LD
       |{_input.LA(-1)!='.'}? DOT       
       ) +        ;
DOT: '.';
SPACE: ' ';
fragment LD: ~[.\n\r ];

Получайте удовольствие и наслаждайтесь ANTLR, это хороший инструмент.

person Cv4    schedule 10.10.2013
comment
привет, не могли бы вы объяснить это немного подробнее, например, как предикаты должны работать в ANTLR и почему грамматика в моем вопросе не работает? Семантические предикаты кажутся мощным инструментом, и я действительно хочу знать, что происходит под ними. Большое спасибо. - person Wudong; 10.10.2013
comment
Пожалуйста, проверьте API ANTLR, относящийся к используемой вами функции. Вы найдете его в (antlr. org / api / Java / org / antlr / v4 / runtime / IntStream.html # LA (int)). Здесь вы видите, что -1 необходимо сравнивать с предыдущим символом, потому что подробно вы смотрите на CharStream (тип _input в лексере (antlr.org/api/Java/org/antlr/v4/runtime/Lexer.html#_input)). Надеюсь, это поможет вам с вашей проблемой. - person Cv4; 10.10.2013