Перейти к основному содержимому

Что это такое

Паттерн Interpreter вычисляет выражения небольшого языка: он строит дерево узлов-выражений — числа, сложения, вычитания — а затем обходит это дерево. Число вычисляется в само себя; сложение вычисляет обе свои стороны и складывает их.

В TypeScript дерево — это размеченное объединение: каждый узел является обычным объектом с полем kind, и одна функция выполняет переключение по этому полю. Поскольку объединение перечисляет все типы узлов, компилятор сообщит об ошибке, если какой-то случай пропущен.

Паттерн подходит для маленьких языков: фильтров, формул, простых правил. Настоящие языки заслуживают настоящих инструментов разбора.


Пример: крошечный калькулятор

Входная строка 3 + 4 - 2 превращается в дерево из узлов number, add и subtract. Один вызов interpret() на корне вычисляет всё выражение.

Одно дерево, одна функция interpret

parse строит дерево слева направо; interpret обходит его и печатает 3 + 4 - 2 = 5. Поддержка * потребовала бы одного нового члена объединения плюс одного нового case — существующие остаются нетронутыми.

Prompt
Напишите программу на TypeScript с паттерном Interpreter: размеченное объединение Expression из узлов number, add и subtract, функцию interpret, которая выполняет переключение по полю kind, и функцию parse, которая превращает строку вида "3 + 4 - 2" в дерево выражений слева направо. Вычислите выражение и напечатайте уравнение вместе с его результатом.
Вывод: программа на TypeScript и захваченный вывод

Когда его использовать

Используйте, когда пользователи или конфигурации выражают логику на небольшом языке вашего собственного дизайна: фильтры поиска, формулы расчёта цен, правила проверки.

Не используйте, когда «язык» состоит из трёх фиксированных вариантов (достаточно обычного switch) — или когда это настоящий язык (возьмите генератор парсеров или готовый движок).


Плюсы и минусы

Плюсы: грамматика отображается один к одному на члены объединения; новые операции — это новые члены; деревья выражений можно строить, проверять и повторно использовать.

Минусы: с ростом грамматики становится болезненным; сам разбор всё равно приходится писать; производительность скромная по сравнению с скомпилированной логикой.