Также вы можете создать производный класс, который будет раскрывать эти методы перегрузки как простые методы с разными именами, отбрасывать любой экземпляр этого класса в новый класс и легко использовать адрес ваших методов-оберток.
Не совсем то, что вы спрашиваете, но в моей грамматике MySQL я должен поддерживать несколько версий сервера, что я делаю, используя семантические предикаты. Это означает, что я могу использовать одну грамматику и включать / отключать определенные пути в зависимости от поля serverVersion
, которое есть в моем парсере. Вот как это выглядит:
alterDatabase:
DATABASE_SYMBOL schemaRef (
createDatabaseOption+
| {serverVersion < 80000}? UPGRADE_SYMBOL DATA_SYMBOL DIRECTORY_SYMBOL NAME_SYMBOL
)
;
и работает очень хорошо. Я могу использовать этот подход даже в лексере (но там с проверкой семантических предикатов по соображениям производительности), который позволяет мне включать и выключать ключевые слова, например:
CONTRIBUTORS_SYMBOL: C O N T R I B U T O R S {serverVersion < 50700}?;
Правильный подход заключается в том, чтобы соотнести каждое правило (или только ключевые правила) с версией синтаксического анализатора.
Прежде всего, вам понадобится поле для отслеживания текущей версии:
@members {
int currentVersion = 1;
}
Теперь предположим, что у вас есть правило RULE_ONE
, которое коррелирует с версией one и RULE_TWO, который соотносится с версией two .
Каждый раз, когда принимается правило, соотнесенное с более поздней версией, поле currentVersion
следует менять:
RULE_ONE
{currentVersion = Math.max(1, currentVersion);} //1 is the parser version
: some_token
;
RULE_TWO
{currentVersion = Math.max(2, currentVersion);} //2 is the parser version
: some_token
;
Таким образом, когда разбор выполнен, вы можете получить максимальную версию, которая была использована.