Компиляторы - выбор инструкций для объявлений типов в 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)" выполняет приведение типа оператора или функции, аналогичной вашему вопросу.

Удачи.

Другие вопросы по тегам