У меня есть lexer, создающий маркеры MACRO для динамического списка макросов, переданных в lexer. Я использовал семантический предикат в самом верхнем правиле лексического анализатора для реализации этой функции:Производительность предиката семантического лексера
MACRO: { macros != null && tryMacro() }? .;
Где tryMacro()
просто проверяет, если какая-либо макрос строка соответствует входной последовательности.
Эффективность такого подхода было очень плохо, и после некоторых исследований я попытался изменить правила лексического анализатора к следующему:
MACRO: . { macros != null && tryMacro() }?;
Это существенно улучшило производительность, но я не понимаю, почему. :) С тех пор как. соответствует любому символу, правило семантического предиката должно вызываться точно столько же раз, сколько и раньше, не так ли? Может ли кто-нибудь объяснить это поведение?
Эта проблема хорошо известна. Я описал на своем целевом блоге ANLTR4 C++: http://www.soft-gems.net/index.php/tools/49-the-antlr4-c-target-is-here. Предикаты в левой части правила предотвращают генерирование DFA, чтобы он не кэшировался, но заставлял их оценивать снова и снова. Это особенно плохо, если у вас много альтов, например. многие ключевые слова (правила lexer - это любопытные альты скрытого корневого контекста). –