Как убрать неоднозначность из этого синтаксиса (antlr4) - PullRequest
0 голосов
/ 01 мая 2018

Я пишу инструмент для генерации диаграммы последовательности из некоторого текста. Мне нужно поддержать этот два синтаксиса:

  1. anInstance:AClass.DoSomething() и
  2. participant A -> participant B: Any character except for \r\n (<>{}?)etc..

Давайте назовем первый синтаксис strict, а второй синтаксис free. В anInstance:AClass.DoSomething() мне нужно, чтобы оно совпадало с to (ID ':' ID), как в синтаксисе strict. Тем не менее, :AClass.DoSomething() будет сначала соответствовать CONTENT. Я подумываю о том, чтобы посмотреть, есть ли ->, но не в состоянии это выяснить.

Strict синтаксис

message
 : to '.' signature
 ;
signature
 : methodName '()'
 ;
to
 : ID ':' ID
 ;
methodName
 : ID
 ;

ID
 : [a-zA-Z_] [a-zA-Z_0-9]*
 ;

Free синтаксис

asyncMessage
 : source '->' target content
 ;
source
 : ID+
 ;
target
 : ID+
 ;
content
 : CONTENT
 ;

ID
 : [a-zA-Z_] [a-zA-Z_0-9]*
 ;
CONTENT
 : ':' ~[\r\n]+
 ;
SPACE
 : [ \t\r\n] -> channel(HIDDEN)
 ;

1 Ответ

0 голосов
/ 02 мая 2018

Вам нужно понять, как работает лексер ANTLR:

  • Используется любое правило, соответствующее самой длинной части ввода (начиная с текущей позиции)
  • В случае, если несколько правил могут совпадать с одним и тем же входом (то есть одинаковой длины), используется первое (в порядке, в котором они определены)

С вашими текущими правилами лексера, CONTENT имеет приоритет, когда вы встречаете :, поэтому ':' ID никогда не будет совпадать.

С ANTLR 4 вам, вероятно, следует использовать режимы в этом случае - когда вы встретите : в свободной форме, переключитесь в «свободный» режим и определите правило лексера CONTENT, чтобы быть доступным только в «свободном» режиме.

См. в этом вопросе , чтобы узнать, как работают режимы лексера ANTLR 4.

...