Визиторы по синтаксическому дереву — различия между версиями
Admin (обсуждение | вклад) |
Admin (обсуждение | вклад) (→Общие комментарии) |
||
Строка 2: | Строка 2: | ||
===Общие комментарии=== | ===Общие комментарии=== | ||
+ | Синтаксическое дерево построено - что дальше? | ||
+ | |||
+ | По синтаксическому дереву можно: | ||
+ | * проанализировать некоторую статистику программы (например, количество операторов присваивания), | ||
+ | * восстановить текст программы (причем, не обязательно на том же языке) | ||
+ | * отформатировать текст программы (создать так называемый Pretty Printer) | ||
+ | * сгенерировать код программы на некотором целевом языке | ||
+ | * выполнить интерпретацию программы | ||
+ | |||
+ | Для каждого такого действия придется совершать обход всех узлов дерева в некотором порядке и совершать действие над каждым узлом в зависимости от типа узла. | ||
+ | |||
+ | При этом, в результате выполнения такого действия будут, как правило, накапливаться некоторые внешние данные (количество операторов присваивания или список команд целевого кода) | ||
+ | |||
+ | Одно из решений - реализовать каждое действие в виде '''виртуального метода''' и переопределить этот метод в каждом типе узлов дерева. Например, реализовать в каждом синтаксическом узле | ||
+ | метод Print для вывода текста программы, метод Generate для генерации участка кода, метод Interpret - для выполнения команды интерпретатора и т.д. | ||
+ | |||
+ | Очевидно, что такое решение захламляет интерфейс каждого узла, делая его тяжеловесным. К тому же, остается открытым вопрос - как хранить внешние данные для каждого такого действия. | ||
+ | |||
+ | Именно для решения подобных проблем и используется '''паттерн Визитор'''. | ||
===Паттерн Визитор=== | ===Паттерн Визитор=== |
Версия 10:38, 19 августа 2014
Содержание
Общие комментарии
Синтаксическое дерево построено - что дальше?
По синтаксическому дереву можно:
- проанализировать некоторую статистику программы (например, количество операторов присваивания),
- восстановить текст программы (причем, не обязательно на том же языке)
- отформатировать текст программы (создать так называемый Pretty Printer)
- сгенерировать код программы на некотором целевом языке
- выполнить интерпретацию программы
Для каждого такого действия придется совершать обход всех узлов дерева в некотором порядке и совершать действие над каждым узлом в зависимости от типа узла.
При этом, в результате выполнения такого действия будут, как правило, накапливаться некоторые внешние данные (количество операторов присваивания или список команд целевого кода)
Одно из решений - реализовать каждое действие в виде виртуального метода и переопределить этот метод в каждом типе узлов дерева. Например, реализовать в каждом синтаксическом узле метод Print для вывода текста программы, метод Generate для генерации участка кода, метод Interpret - для выполнения команды интерпретатора и т.д.
Очевидно, что такое решение захламляет интерфейс каждого узла, делая его тяжеловесным. К тому же, остается открытым вопрос - как хранить внешние данные для каждого такого действия.
Именно для решения подобных проблем и используется паттерн Визитор.
Паттерн Визитор
Описание паттерна Посетитель в курсе Паттерны проектирования