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

У меня есть раздел грамматики ALTLR, который выглядит следующим образом:

mainfilter: mandatoryfilter (optionalfilter1)? (optionalfilter2)? (optionalfilter3)? ;
mandatoryfilter: 'NAME' '=' ID;
optionalfilter1: 'VALUE1' EQ ID; 
optionalfilter1: 'VALUE2' EQ ID; 
optionalfilter1: 'VALUE3' EQ ID; 
EQ: '=' ;

ID: [A-Za-z0-9]+
//Also I will skip spaces and whitespace

Мое требование состоит в том, что правила "факультативного фильтра" могут встречаться в любом порядке.Один из подходов, о котором я думаю, это переписать правило, как показано ниже, а затем проверить его с помощью прослушивателя:

mainfilter: mandatoryfilter (optionalfilter1|optionalfilter2|optionalfilter3)*;

Другой способ добиться этого - поместить все комбинации в одно правило синтаксического анализатора каждое.но это не может быть более мудрым решением, если число необязательных фильтров увеличивается.

Пример ввода:

NAME = BOB VALUE1=X VALUE2=Y VALUE3 = Z
NAME = BILL VALUE3=X VALUE1=Y VALUE2 = Z

моя грамматика успешно проанализирует первый вход, но не второй.

Так есть ли элегантный способ справиться с этим в самой моей грамматике?

1 Ответ

0 голосов
/ 03 июня 2018

Так есть ли элегантный способ справиться с этим в самой моей грамматике?

Нет.

Обычно, ноль или более совпадают, а затем после синтаксического анализа этоподтверждается, что фильтр выполняется только один раз.

Возьмем, к примеру, спецификацию языка Java, которая определяет, что определение класса может иметь ноль или более модификаторов класса (часть {ClassModifier})

NormalClassDeclaration:
  {ClassModifier} class Identifier [TypeParameters] [Superclass] [Superinterfaces] ClassBody

ClassModifier:
  (one of) 
  Annotation public protected private abstract static final strictfp

, что соответствует public public class Foo {}.Это отклонено на этапе после разбора.

...