Как правильно расширить грамматику ANTLR4?

У меня есть требование, когда я хочу расширить существующую грамматику A дополнениями, определенными в грамматике B, чтобы создать грамматику C.

Я уже пытался импортировать грамматику A в B, но при этом выбираются только определенные вещи, определенные в грамматике A. Я предполагаю, что неиспользуемое содержимое A в B пропускается при создании классов. Это имеет смысл, поскольку требуется не наследовать, а смешивать/объединять/объединять две грамматики.

Просто для понимания (исходная грамматика огромна), пример:

Файл : A.g4:

grammar A;

keywords
    : X
    | Y
    | Z
    ;

X: 'X';
Y: 'Y';
Z: 'Z'; 

Файл : B.g4:

grammar B;

keywords
    : A
    | B
    | C
    ;

A: 'A';
B: 'B';
C: 'C'; 

Файл : C.g4:

grammar C;

keywords
    : X
    | Y
    | Z
    | A
    | B
    | C
    ;

X: 'X';
Y: 'Y';
Z: 'Z';
A: 'A';
B: 'B';
C: 'C'; 

Примечание. У меня нет возможности управлять грамматикой А напрямую, но я хочу сохранить все функции грамматики А вместе с дополнительными правилами/ключевыми словами и т. д., определенными в грамматике Б, как показано выше.

Любая помощь будет высоко ценится. Спасибо.


person Chitral Verma    schedule 08.01.2020    source источник
comment
Во всех ваших грамматиках отсутствует оператор импорта. Пожалуйста, добавьте их еще.   -  person Mike Lischke    schedule 08.01.2020


Ответы (1)


Импорт грамматики может работать не так, как вы ожидаете. Правила в импортируемой грамматике имеют приоритет над теми же именованными правилами в импортированной грамматике. Таким образом, вы не можете переопределить существующее правило в вашей основной грамматике. См. также описание в репозитории ANTLR4. :

Думайте об импорте как об умном выражении включения (которое не включает уже определенные правила).

Однако должна быть возможность переопределить правило во второй грамматике импорта. В вашем случае вы бы не определили keywords в своей основной грамматике (я предполагаю, что это C). Импортируйте грамматики A и B в обратном порядке, если вы хотите, чтобы правило keywords B имело приоритет над правилом A.

import B, A;

Это также продемонстрировано на изображении из этого файла Markdown:

введите здесь описание изображения

Правило r из грамматики G2 игнорируется, так как оно импортируется последним, поэтому G3 как бы "отменяет" его.

person Mike Lischke    schedule 08.01.2020
comment
Майк, я понимаю, как работает импорт, но это связано со слиянием двух составных грамматик для создания третьей грамматики. - person Chitral Verma; 09.01.2020
comment
Тогда мой ответ должен вам помочь. - person Mike Lischke; 09.01.2020
comment
Таким образом, вы не можете [переписать] существующее правило в вашей основной грамматике, это немного сбивает с толку. Вы имеете в виду, что B не может изменить правило в C? Не похоже, что OP пытается это сделать, но вместо этого B изменяет правило из A. - person Daniel; 14.01.2020
comment
Импорт состояния документов похож на операцию включения, которая игнорирует уже существующие правила. Это должно прояснить, что вы не можете переопределить правило в грамматике импорта. Однако, если ваша импортируемая грамматика импортирует 2 другие грамматики, и обе они содержат правило, которого нет в импортирующей грамматике, это правило будет импортировано туда. Какая из двух зависит от порядка импортированных грамматик. Грамматика, содержащая окончательное правило, должна быть импортирована первой (потому что второй импорт больше не может переопределить это правило). Это именно то, что показывает изображение. - person Mike Lischke; 14.01.2020