Трехадресные таблицы кодов и символов

Я работаю над хобби-перенацеливаемым компилятором C в OCaml, и я создаю его снизу вверх. Пока у меня есть сокращенный аннотированный тип AST:

type 'e expr =
    | Int of 'e * int
    | Var of 'e * var
    | Neg of 'e * 'e expr
    | Add of 'e * 'e expr * 'e expr
    | Sub of 'e * 'e expr * 'e expr

и тип трехадресного кода (снова сокращенный):

type node = Copy of location * location
          | Unary of location * unary_op * location
          | Binary of location * location * binary_op * location

and location = Temp of int | Int of int | Var of string

and unary_op = Neg

and binary_op = Add | Sub

У меня есть написанные функции, которые преобразуют AST в список узлов TAC, игнорируя аннотации. В связи с этим у меня два вопроса:

  1. Что мне делать по-другому при преобразовании AST с аннотациями типа в список узлов TAC? Должен ли я также добавлять аннотации к узлам TAC? Это позволило бы мне позже преобразовать типы int/char высокого уровня в типы более низкого уровня, такие как I16/I8.

  2. Как мне справиться с областью видимости? Что делать, если у меня есть два Var с одинаковым именем в разных областях?




Ответы (1)


Вопрос о том, как вы передаете аннотации в свой TAC, остается открытым, но я согласен, что вы, вероятно, захотите это сделать.

Один из подходов к определению области действия — стирание имени; при разрешении областей вы заменяете каждый уникальный идентификатор уникальным «именем» (или непосредственно ссылкой на запись в таблице символов). (Иногда это называется gensymming, после традиционной функции Lisp gensym.) Более формально это -редукция, термин, взятый из исчисления. Это будет работать для таких языков, как C, в которых имена недоступны для среды выполнения.

Языки, в которых интроспекция во время выполнения имеет доступ к именам (Python, Javascript), несколько усложняют этот процесс, но вы все же можете связать каждое использование имени с определенной областью. В языках, где области действия могут быть динамическими (Perl, Lisp), вам придется ввести в TAC операцию разрешения имен.

person rici    schedule 19.06.2015
comment
Большое Вам спасибо. То есть вместо отдельных узлов Temp и Var в TAC я бы сделал их одним узлом Symbol, содержащим указатель на запись в таблице символов? - person jamestn529; 19.06.2015
comment
@jamestn: есть много подходов. Это, безусловно, один из способов сделать это. Вам также необходимо подумать о статическом и автоматическом времени жизни. - person rici; 20.06.2015
comment
Я думаю, что статический или автоматический — это скорее вопрос типа, не так ли? - person jamestn529; 20.06.2015