Я беру класс проектирования компилятора, в котором мы должны реализовать наш собственный компилятор (с использованием гибкости и bison). У меня был опыт синтаксического анализа (написания синтаксических анализаторов EBNF и рекурсивного спуска), но я пишу компилятор впервые.
Дизайн языка довольно открытый (профессор оставил это нам). В классе профессор перешел к созданию промежуточного кода. Он сказал, что нам не обязательно строить абстрактное синтаксическое дерево или дерево синтаксического анализа во время синтаксического анализа, и что мы можем генерировать промежуточный код по ходу работы.
Я нашел это запутанным по двум причинам:
Что делать, если вы вызываете функцию до того, как она будет определена? Как вы можете решить задачу ветки? Я полагаю, вам нужно будет взять за правило определять функции перед их использованием или, может быть, заранее определять их (как это делает C?)
Как бы вы поступили с условными операторами? Если у вас есть if-else
или даже просто if
, как можно разрешить цель перехода для if
, когда условие false
(если вы генерируете код на ходу)?
Я планировал сгенерировать AST, а затем пройти по дереву после его создания, чтобы разрешить адреса функций и целей ветвления. Это правильно или я что-то упустил?