Вот вторая версия в Common Lisp. На этот раз я использую шаблон .
Я использую функцию, которая сопоставляет шаблон с данными Lisp. PMATCH: MATCH - это расширенная версия сопоставления с образцом, найденная в книге Winston / Horn, Lisp, 3rd Edition. Доступны аналогичные функции сопоставления с образцом.
Данные такие же, как в моем другом ответе.
Функция отображения дерева изменена для использования сопоставителя шаблонов. Функция PMATCH: MATCH возвращает T или связанный список привязок, если сопоставление прошло успешно. Возвращает NIL, если совпадение не было успешным. PMATCH: INSTANTIATE-PATTERN принимает шаблон и набор привязок. Возвращает новую структуру списка, в которой переменные шаблона заменяются привязками.
(defun treemapp (tree pattern transformer)
(cond ((null tree) nil)
((consp tree)
(let ((bindings (pmatch:match pattern tree)))
(if bindings
(pmatch:instantiate-pattern transformer bindings)
(cons (node-type tree)
(mapcar (lambda (child)
(treemapp child pattern transformer))
(node-children tree))))))
(t tree)))
В примере теперь используются шаблоны.
Шаблон представляет собой структуру списка. Символ # соответствует одному элементу и создает привязку для символа. Символ $ соответствует списку элементов и создает привязку для символа.
Трансформатор - это шаблон, который будет создан с привязками.
(defun example1 ()
(pprint (treemapp *tree*
'(NP (NP (#?type bank)) (PP #$children))
'(NP (NP (#?type bank) #$children)))))
Запуск этого кода возвращает тот же результат, что и в моем другом ответе.