ANTLR с нежадными правилами

Хотелось бы иметь следующую грамматику (ее часть):

expression 
: 
expression 'AND' expression
| expression 'OR' expression
| StringSequence
;

StringSequence
: 
StringCharacters
;

fragment
StringCharacters
: StringCharacter+
;

fragment
StringCharacter
: ~["\]
| EscapeSequence
;

Он должен соответствовать таким вещам, как «a b c d f» (без кавычек), а также таким вещам, как «a AND b AND c».

Проблема в том, что мое правило StringSequence является жадным и также использует OR / AND. Я пробовал разные подходы, но не мог заставить мою грамматику работать правильно. Возможно ли это с ANTLR4? Обратите внимание, что я не хочу заключать каждую строку в кавычки. Размещение кавычек отлично работает, потому что правило становится не жадным, то есть:

StringSequence
: '"' StringCharacters? '"'
;

person Angel Todorov    schedule 31.03.2015    source источник


Ответы (2)


У вас нет правила пробелов, поэтому StringCharacter соответствует всему, кроме символов кавычек и обратной косой черты (+ escape-последовательность). Включите правило пробелов, чтобы оно соответствовало отдельным токенам И / ИЛИ. Кроме того, я рекомендую определить правила лексера для строковых литералов ('AND', 'OR') вместо того, чтобы встраивать их в правила (синтаксического анализатора). Таким образом, вы не только получите говорящие имена для токенов (вместо автоматически сгенерированных), но и сможете лучше контролировать порядок совпадения.

person Mike Lischke    schedule 01.04.2015

И все же наивное решение:

StringSequence : 
  (StringCharacter | NotAnd | NotOr)+
;
fragment NotAnd :
  'AN' ~'D'
| 'A' ~'N'
;
fragment NotOr:
  'O' ~('R')
;
fragment StringCharacter :
  ~('O'|'A')
;

С правилами пробелов становится немного сложнее. Другое решение - семантические предикаты, которые смотрят вперед и предотвращают чтение ключевых слов.

person CoronA    schedule 31.03.2015