Я работаю над переводчиком для игрушечного языка, просто чтобы научиться создавать переводчика. Я уже реализовал простой синтаксический анализатор для грамматики, которая генерирует дерево разбора. Теперь обычным способом оценки дерева разбора будет использование полиморфизма в узлах дерева разбора, с кодом, который выглядит примерно так (в Python):
class Node:
def __init__(self,left,right):
self.left=left
self.right=right
def evaluate(self):
print "throw an exception"
class AddNode(Node):
def evaluate(self):
return evaluate(self.left)+evaluate(self.right)
class SubNode(Node):
def evaluate(self):
return evaluate(self.left)-evaluate(self.right)
Метод оценки переопределяется в каждом потомке узла и защищается, чтобы вести себя как нужно. Значение выражения можно найти, просто вызвав методуборка () в корне.
Другой способ состоит в том, чтобы не иметь какой-либо функции оценки в узлах, но генерировать дерево разбора, которое просто назначает тип узлу. Код оценки выполняется в отдельной функции, которая рекурсивно исследует каждый узел и решает, как его оценить. Это приведет к функции с большой конструкцией «if else», переключателем или таблицей переходов.
Почти в каждом месте, куда я смотрю, и то, чему меня учили в колледже, кажется, указывает на то, что первый метод всегда лучше. Я не совсем понимаю, почему первый метод должен превосходить второй. Почему полиморфизм обязательно лучше в этом случае? Функция с большой таблицей «если еще» отсутствует, но в основном тот же код все еще там, но перемещен в другое место и разбросан по множеству разных классов.
Это привлекло мое внимание, потому что я подумал, что мне может понадобиться изменить значение некоторых операторов позже, возможно, даже разрешить переопределение операторов во время выполнения. Я также отношусь к вызовам функций так же, как к операторам, поэтому было бы неплохо иметь что-то вроде таблицы переходов, которую можно добавить во время выполнения.
Вероятно, есть какое-то существенное преимущество с первым методом, которого я сейчас не вижу. Может кто-нибудь указать на это?