В нашем проекте мы следуем этой структуре. Есть файлы FooLexerBase.g
и FooLexerLang1.g
, FooLexerLang2.g
и так далее. Базовая грамматика определяет общие правила токена. Токены, которые зависят от языка, не определены в базе, но на них можно ссылаться. Эти токены определены в языковых грамматиках, которые также включают в себя основание.
Итак, в основном это выглядит примерно так:
FooLexerBase.g
:
lexer grammar FooLexerBase;
...
FLOATING_POINT
: DIGIT+ EXPONENT
| DIGIT+ DECIMAL_SEP DIGIT* EXPONENT?
| DECIMAL_SEP DIGIT+ EXPONENT?;
...
DIGIT
и EXPONENT
определены в базе, поскольку они являются общими, в то время как DECIMAL_SEP
зависит от языка.
Например, FooLexerGerman.g
выглядит следующим образом:
lexer grammar FooLexerGerman;
import base = FooBase;
...
fragment
DECIMAL_SEP: ',';
...
Наконец, грамматика синтаксического анализатора является общей для всех языков. Это определяется следующим образом:
parser grammar FooParser;
options {
tokenVocab = FooLexerBase;
}
...
Важно, чтобы не обрабатывал FooLexerBase
с помощью ANTLR, но передавал все остальные грамматики через него.
Во время выполнения высоздайте парсер и передайте соответствующий лексер в качестве аргумента конструктору. Я думаю, это выглядит более или менее одинаково на любом языке программирования (мы используем Java).