Как правилно да разширите граматика на 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'; 

Забележка: Нямам опцията да манипулирам директно граматика A, но искам да запазя цялата функционалност в граматика A заедно с допълнителните правила/ключови думи и т.н., дефинирани в граматика B, както е показано по-горе.

Всяка помощ ще бъде високо оценена. Благодаря.


person Chitral Verma    schedule 08.01.2020    source източник
comment
Във всичките ви граматики липсва оператор за импортиране. Моля, добавете ги още.   -  person Mike Lischke    schedule 08.01.2020


Отговори (1)


Импортирането на граматика може да не работи, както очаквате да работи. Правилата в импортиращата граматика имат предимство пред правилата със същото име в импортираната граматика. По този начин не можете да отмените съществуващо правило във вашата основна граматика. Вижте също описанието в ANTLR4 repo :

Мислете за импортирането като по-скоро като интелигентен оператор за включване (който не включва правила, които вече са дефинирани).

Трябва обаче да е възможно да се замени правило във втора граматика за импортиране. Във вашия случай не бихте дефинирали 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