Компиляторы - выбор инструкций для объявлений типов в AST
Я изучаю компиляторы и создаю генератор кода для простого языка, который работает с двумя типами: символами и целыми числами.
После того, как пользовательский ввод был отсканирован сканером, а затем проанализирован синтаксическим анализатором, я получаю AST-представление ввода. Я сделал генерацию кода для еще более простого языка, который обрабатывает выражения только с целыми числами, операторами и переменными.
Однако с этим новым языком я иногда получаю поддерево для объявления типа, например:
(IS TYPE (x) (INT))
который говорит, что х имеет тип INT.
Должен ли быть случай в моем генераторе кода, который имеет дело с этими объявлениями типов? Или это просто для семантического анализатора для проверки типов, так что я должен просто предположить, что типы проверены, игнорировать эту часть дерева и просто присвоить значение для x?
2 ответа
Если это декларация
(IS TYPE (x) (INT))
тогда х следует выложить в память. В случае C и автоматических переменных локальные автоматические переменные размещаются в стеке. Чтобы выделить необходимый размер стека, вы должны знать размеры всех локальных переменных и их размеры.
Если эта переменная хранится в регистре, вы должны выбрать регистр необходимого размера (подумайте о x86 с: AL, AX, EAX, RAX - тот же регистр с разными размерами), если у вашей цели есть такой.
Кроме того, тип необходим, когда в AST имеется неоднозначная операция, которая может работать с различными размерами данных (например, char, short, int - или 8-разрядный, 16-разрядный, 32-разрядный и т. Д.). А для некоторых ассемблеров размер данных кодируется в самой инструкции; поэтому codegen должен помнить размеры переменных.
Или, если тип операции не был записан в AST, ADD:
(ADD (x) (y))
может означать как float, так и int сложения (ADD
или же FADD
инструкции), поэтому для выбора правильного варианта в codegen необходимы типы x и y.
Обе ситуации возможны, вам нужно больше рассказать о своем языке, чтобы увидеть, действительно ли вам нужно добавить эту функцию в генератор кода или пропустить ее как ненужную, и избежать дополнительной работы с этой сложной и интересной темой разработки языка программирования.,
Являетесь ли вы "генератором кода" программой, которая получает в качестве входного кода язык программирования (может быть, маленький) и выводит код на другом языке программирования (может быть, маленький)?
Этот инструмент обычно называют "переводчиком".
Являетесь ли вы "генератором кода" программой, которая получает на вход язык программирования и выводит ассемблер / байт-код, как язык программирования?
Этот инструмент обычно называют "компилятором".
Примечание: "стопка" является синонимом "стопки".
Обычно AST хранит тип операции или вызов функции. Пример в c:
...
int a = 3;
int b = 5;
float c = (float)(a * b);
...
Последняя строка генерирует AST, похожий на этот, (пропустите AST для других строк):
..................................................................
..................................................................
......................+--------------+............................
......................| [root] |............................
......................| (no type) = |............................
......................+------+-------+............................
.............................|....................................
.................+-----------+------------+.......................
.................|........................|.......................
...........+-----+-----+....+-------------+-------------+.........
...........| (int) c |....| (float) (cast operation) |.........
...........+-----------+....+-------------+-------------+.........
..........................................|.......................
....................................+-----+-----+.................
....................................| (int) () |.................
....................................+-----+-----+.................
..........................................|.......................
....................................+-----+-----+.................
....................................| (int) * |.................
....................................+-----+-----+.................
..........................................|.......................
..............................+-----------+-----------+...........
..............................|.......................|...........
........................+-----+-----+...........+-----+-----+.....
........................| (int) a |...........| (float) b |.....
........................+-----------+...........+-----------+.....
..................................................................
..................................................................
Обратите внимание, что "(float)" выполняет приведение типа оператора или функции, аналогичной вашему вопросу.
Удачи.