Разбор одного слова в несколько токенов при пропуске пробела - PullRequest
0 голосов
/ 25 октября 2018

У меня есть язык, где пробелы незначительны, поэтому я его пропускаю.Вот подмножество грамматики, которую я имею до сих пор:

start: expr <EOF>;
expr
    : atom
    | expr '|' expr
    | expr expr+
    | '{' expr '}'
    ;
atom
    : ATOM_TOKEN
    ;
fragment LETTER: [a-zA-Z];
fragment DIGIT: [0-9];
ATOM_TOKEN: (LETTER | DIGIT)+;
WS: [ \r\n\t]+ -> skip;

При выполнении на следующем входе (обратите внимание на пробел и его отсутствие) он правильно создает желаемое ожидаемое дерево разбора:

{hello42   |  hi world}|{good bye} red blue green

Parse Tree

Теперь моя проблема в том, что в идеале я хотел бы сделать atom вложенным правилом, чтобы я мог выбирать характерные фигуры.

Вот пример грамматики:

atom: atomToken+;
atomToken
    : LETTERS
    | DIGITS
    ;
LETTERS: LETTER+;
DIGITS: DIGIT+;

и результат выполнения he11o через нее (примечания 1 вместо L):

Atom Parse Tree

Проблема с этим подходом состоит в том, что поскольку пробелы игнорируются, что-то вроде he11o world теперь будет анализироваться как один atom.

Есть ли что-то очевидное, что я упускаю?Из моего исследования возникла пара возможностей.

  1. Напишите вторичную грамматику, чтобы использовать ее, когда мне действительно нужно извлечь куски atom.Это одно из самых простых решений.
  2. Реализация какого-либо токена-инъекции путем создания подкласса сгенерированного Lexer.Это кажется очень странным, и я хотел бы избежать этого, если нет лучшего варианта.
  3. Делать что-то с лексическими режимами или каналами, чтобы пропуски пропускались только условно?Я почти уверен, что это не сработает, поскольку контекст для запуска этого будет исходить от синтаксического анализатора, и, насколько я знаю, вы не можете изменить поведение лексера из правил синтаксического анализатора.
  4. Не пропускайте пробелыи вместо этого засорять основную грамматику всеми возможными пробелами.

Любая помощь приветствуется.

...