Прошу прощения, если мой вопрос к субъективному, я постараюсь сформулировать его как можно яснее.
Итак, я пишу компилятор на C ++ (используя flex, bison и llvm). Мои базовые c сущности - это узлы AST, выражения, операторы и т. Д. c.
Теперь я пытаюсь реорганизовать мой компилятор, применяя принципы чистой архитектуры, где, среди прочего, внутренние слои ничего не знают о внешнем слои, ни о внешних зависимостях. Мой текущий план состоит в том, чтобы создать 3 слоя.
самый внутренний будет определять структуры данных AST, определение SourceFile et c. Этот уровень ничего не будет знать о семантике и не будет выполнять оценку AST. Просто структуры данных и определения. Здесь, например, я определяю, что существует такая вещь, как в IfStatement, и что она состоит из выражения (условия) и списка операторов (тела). Но не проверял бы достоверность какой-либо семантики.
Второй слой 1012 * будет анализатором. Он примет AST и выполнит различные проверки и преобразования в него. Это будет иметь дело с областями видимости, корректностью типов, обнаружением недостижимых операторов и т. Д. c.
третий слой вводит внешние зависимости (такие как бизон и llvm) и будет содержать клей код, чтобы заставить все это работать.
Проблема:
Я не уверен, как проектировать мои классы AST (самый внутренний слой), не загрязняя его анализатором или особенности llvm.
В данный момент анализатор должен вводить метаданные в AST во время его анализа. Таким образом, в моих классах AST у меня есть поля c, определяемые анализатором. Грязное решение.
Кроме того, llvm должен внедрить свои собственные метаданные на этапе генерации кода. Таким образом, в моих классах AST у меня есть llvm speci c поля. Очень грязное решение: внутренние части моего приложения теперь зависят от внешних и, что еще хуже, от внешних зависимостей.
Тем не менее, я не вижу выхода из этого. Как внешние слои могут вводить свои метаданные в AST без зависимости от них? Я могу придумать 2 способа, ни один из которых не выглядит очень хорошим:
AST не имеет прямой ссылки на какие-либо особенности внешнего слоя. Внешние слои должны использовать хэш-карту или аналогичную структуру отображения для хранения / получения метаданных каждого узла AST. Но доступ к карте намного медленнее, чем прямой доступ к полям, который у меня сейчас есть с моей грязной архитектурой.
Объекты AST будут ссылаться на свои метаданные через некоторый интерфейс. Интерфейс определен на внутреннем уровне, но реализован на внешнем, поэтому соблюдайте чистую архитектуру. Недостаток, который я вижу в этом, заключается в том, что мне придется вводить фабричный шаблон при генерации AST, и много типов приведений при его анализе. Кроме того, классы внутреннего уровня будут ссылаться на некоторые поля «метаданных», которые они на самом деле никогда не используют и не нуждаются.
Есть что-то, что я пропускаю или что я неправильно понял в чистой архитектуре? Есть ли лучший шаблон проектирования или я должен go опередить один из упомянутых выше компромиссов?