В моем небольшом компиляторе у меня в настоящее время есть ручной AST.
Я рассматривал идею иметь посетителя, который бы присматривал за узлами определенного типа X
и заменял бы их узламивведите X'
.Проблема в том, что кажется, что это не легко реализовать с помощью шаблона посетителя.
Единственный способ, с помощью которого я смогу выполнить эту работу, - это иметь методы visit () для всех видов узлов, которые могут иметь узел типа X
в качестве дочернего, и поместить туда заменяющую логику мой узел,но может быть много таких узлов.Кроме того, если позже я решу добавить новый тип узла, я рискую не забыть проверить этот новый особый случай у этого посетителя.
В чем проблема, которую я пытаюсь решить:
Для текущего случая в моем дереве есть узлы типа FunctionCall
, которые передают только имя операции и ее параметры.
Я бы хотел заменить их на MethodInvocation
, с соответствующим преобразованием OOish:
m(A, B) -> A.m(B)
m(n(A, B), C) -> (A.n(B)).m(C)
Конечно, это можно сделать тысячами разных способов, и проще всего просто попытаться рассмотреть только класс Call
, в котором могут илиможет не существовать цели, но я бы хотел быть настолько явным, насколько это возможно (то есть, используя разные виды узлов), чтобы выразить разные вещи, если это возможно.