• Nenhum resultado encontrado

Compiladores. Árvore de derivação anotada. Geração de TAC para as principais construções. tradução em código TAC de expressões

N/A
N/A
Protected

Academic year: 2021

Share "Compiladores. Árvore de derivação anotada. Geração de TAC para as principais construções. tradução em código TAC de expressões"

Copied!
6
0
0

Texto

(1)

Compiladores

Geração de

código intermediário (2)

Geração de TAC para

as principais construções

• Geração de código de três endereços:

– Expressões

– Declarações (escopo simples)

– Declarações (escopos aninhados)

– Comandos de atribuição

– Arrays e Registros

– Expressões booleanas

– Comandos de decisão

– Comandos de iteração

tradução em código TAC de

expressões

S

id := E

E

E

1

+ E

2

E

E

1

* E

2

E

(E

1

)

E

id

T1 := Y * Z

T2 := X + T1

A := T2

Exemplo:

A := X + Y * Z

Usa-se dois mecanismos: 1. Atributos sintetizados:

• O atributo ‘local’ armazena o nome da variável • O atributo ‘codigo’ armazena o código TAC sintetizado 2. Funções auxiliares:

• A função “geracod” escreve (na tela) código

• A função “novo_tmp” retorna um nome de temporário tmp1, tmp2...

Expressões (cont.)

(“ || “ significa concatenação)

S

id :=E

{S.codigo = E.codigo ||

geracod(id.local”:=“ E.local)}

E

E

1

+ E

2

{E.local = novo_tmp();

E.codigo = E

1

.codigo || E

2

.codigo ||

geracod (E.local “:=“ E

1

.local “+” E

2

.local) ; }

E

E

1

* E

2

{E.local = novo_tmp();

E.codigo = E

1

.codigo || E

2

.codigo ||

geracod (E.local “:=“ E

1

.local “*” E

2

.local) ; }

E

(E

1

)

{E.local = E

1

.local; E.codigo = E

1

.codigo }

E

id

{E.local = id.local; E.codigo = “ ”}

Árvore de derivação anotada

S id := E E + E E * E id id id cod = “ “ local=A cod = “ “ local=X cod = “ “ local=Y cod = “ “ local=Z cod = T1:=Y*Z || T2:=X+ T1 local=T2 cod = “ “ local=X cod = “ “ local=Y cod = “ “ local=Z cod = T1:=Y*Z local=T1

A := X + Y * Z

cod = T1:=Y*Z || T2:=X+ T1 || A := T2

Reaproveitamento de temporários

Deve-se poupar os temporários

Usa-se um contador c

– Valor inicial: c = 0

– Quando se gera um novo temporário: 1. Usa-se o valor atual c;

2. Incrementa c de 1 unidade: c++. • (Ou seja: “tmp_c++ := alguma_coisa”)

– Cada vez que se usa um temporário como operando, diminui-se c de uma unidade.

Exemplo: X := A*B + C*D – E*F

– Necessita apenas 2 temporários:

C =0 tmp0 := A*B C=1 tmp1 := C*D C=2 tmp0 := tmp0 + tmp1 C=1 tmp1 := E*F C=2 tmp0 := tmp0 – tmp1 C=1 X := tmp0 C=0

(2)

TAC

• Geração de código de três endereços:

– Expressões

– Declarações (escopo simples)

– Declarações (escopos aninhados)

– Comandos de atribuição

– Arrays e Registros

– Expressões booleanas

– Comandos de decisão

– Comandos de iteração

Parsing de declarações

• Em linguagens como C, Pascal e Fortran, variáveis de

um mesmo procedimento pertencem a um mesmo grupo

– Associa posições de memória a nomes locais de procedimentos – Calcula um deslocamento

• Antes da primeira declaração zera o deslocamento

• Quando o parser analisa declarações, ele:

– atualiza na tabela de símbolos o endereço de memória relativo: • à base da área estática de dados para declarações estáticas

(globais)

• À base da pilha para dados locais no registro de ativação

• A geração de endereços pode ter máquina alvo em

mente:

– Leva em consideração o tamanho da palavra, necessidade de alinhamento, etc...

– ex. inteiros consecutivos diferem de 4 bytes

Parsing de declarações

• Usar tradução dirigida pela sintaxe:

– atributos:

• Nome (lexema associado a um identificador) • Tipo (expressão de tipo)

• Size (tamanho de representação do tipo) • deslocamento

• Procedimento auxiliar:

– insert(nome, tipo, deslocamento):

• cria uma nova entrada na tabela de símbolos para nome, e lhe confere o tipo e o endereço relativo deslocamento

• Expressões de tipos:

– Tipos básicos (int, real, ...)

– array(num, tipo)

– ponteiro(tipo)

Parsing de declarações

• Tamanhos de alguns tipos:

– inteiro: 4 bytes

– real: 8 bytes

– array: número de elementos x tamanho do tipo

– ponteiro: 4 bytes

• Gramática típica a tratar:

P →→→→MD M →→ εεεε→→ D →→→→D ; D D →→→→id : T T →→→→int T →→→→real T →→→→array [num] of T1 T →→→→↑T1

Esquema de tradução

P →MD M → ε {desloc = 0; } D →D ; D

D →id : T { insert (id.nome, T.tipo, desloc); desloc = desloc + T.size} T →int {T.tipo = int; T.size = 4; } T →real {T.tipo = real; T.size = 8; } T →array [num] of T1 {T.tipo = array(num.val, T1.tipo);

T.size = num.size* T1.size; } T →↑T1 {T.tipo = ponteiro(T1.tipo); T.size = 4; }

Árvore de derivação - a: int; b: real;

P D M ε ; {desloc =0} {insert(a,int,0); desloc:=desloc+4} {adSimb(b,real,4); desloc:=desloc+8} tipo=real tam=8 D id : int T {tipo=int tam=4} nome=a D T : real id nome=b

(3)

TAC

• Geração de código de três endereços:

– Expressões

– Declarações (escopo simples)

– Declarações (escopos aninhados)

– Comandos de atribuição

– Arrays e Registros

– Expressões booleanas

– Comandos de decisão

– Comandos de iteração

Controlando Escopo

• Cada procedimento possui um escopo onde

endereços relativos devem ser criados

• Usar uma tabela de símbolos para cada escopo

P →

MD

M → ε

D →

D; D

D →

id : T

D

proc id; ND; S

N

→ ε

Ações semânticas

• geratab(anterior):

– cria uma tabela de símbolos retornando um apontador para a mesma. “anterior” é um ponteiro para a tabela criada anteriormente

• insert(tabela, nome, tipo, deslocamento)

– cria uma nova entrada para nome na tabela de símbolos

• deftam(tabela, largura):

– registra a largura acumulada de todas as entradas de tabela no cabeçalho associado a tabela de símbolos

• insert_proc(tabela, nome, tipo, ptr_tab)

– cria uma nova entrada para o nome de procedimento nomena tabela de símbolos. Ptr_tab aponta para a tabela associada a nome.

Estruturas auxiliares

• Pilhas de tabela de símbolos (tabPtr)

• Pilhas de deslocamentos (desloc)

• Métodos:

– Push(t, desloc), push(t, tabPtr)

– Pop(desloc), pop(tabPtr)

– Top(desloc), top(tabPtr)

Exemplo: esquema de tradução para

gerar uma árvore de tabelas de símbolos

P

MD

M

→ ε

D

D; D

D

id : T

D

proc id; ND; S

N

→ ε

T

int

T

real

T

array [num] of T

1

T

^T

1

Exemplo: esquema de tradução para

gerar uma árvore de tabelas de símbolos

P →

MD

M → ε

{t=geraTab(nil);

push(t,tabPtr);

push(0,desloc)}

D →

D; D

D →

id : T

D →

proc id; ND; S

(4)

Exemplo: esquema de tradução para

gerar uma árvore de tabelas de símbolos

P

MD

{defTam(top(tabPtr),top(desloc));

pop(tabPtr);

pop(desloc)}

M

→ ε

D

D; D

D

id : T

D

proc id; ND; S

Exemplo: esquema de tradução para

gerar uma árvore de tabelas de símbolos

P

MD

{defTam(top(tabPtr),top(desloc)); pop(tabPtr); pop(desloc)}

M

→ ε

{t=geraTab(nil); push(t,tabPtr); push(0,desloc)}

D

D; D

D

id : T

{insert (top(tabPtr),id.nome, T.tipo, top(desloc)); top(desloc) = top(desloc) + T.tam}

D

proc id; ND; S

Exemplo: esquema de tradução para

gerar uma árvore de tabelas de símbolos

P →MD {defTam(top(tabPtr),top(desloc)); pop(tabPtr); pop(desloc)} M → ε {t=geraTab(nil); push(t,tabPtr); push(0,desloc)} D →D; D

D →id : T {insert (top(tabPtr),id.nome, T.tipo, top(desloc)); top(desloc) =top(desloc) + T.tam}

D →proc id; ND; S {t=top(tabPtr); defTam(t, top(desloc)); pop(tabPtr); pop(desloc); insert(top(tabPtr),id.nome, t)}

Exemplo: esquema de tradução para

gerar uma árvore de tabelas de símbolos

N

→ ε

T

int

T

real

T

array [num] of T

1

T

^T

1

Exemplo: esquema de tradução para

gerar uma árvore de tabelas de símbolos

N → ε {t=geraTab(top(tabPtr));

push(t,tabPtr); push(0,desloc)}

T →int {T.tipo = int; T.tam = 4}

T →real {T.tipo = real; T.tam = 8}

T →array [num] of T1 {T.tipo = arranjo(num.val, T1.tipo); T.tam = num.val* T1.tam}

T →^T1 {T.tipo = ponteiro(T1.tipo);

T.tam = 4} nil

Exemplo

a, real, 0

a: real; b: int; proc p1; c: real; ---end p1; proc p2; d: array[5] of int; proc p3; e,f: real; ---end p3; ---end p2;

(5)

---nil

Exemplo

a, real, 0

b, int, 8

a: real; b: int; proc p1; c: real; ---end p1; proc p2; d: array[5] of int; proc p3; e,f: real; ---end p3; ---end p2; ---nil

Exemplo

a, real, 0

b, int, 8

p1,

a: real; b: int; proc p1; c: real; ---end p1; proc p2; d: array[5] of int; proc p3; e,f: real; ---end p3; ---end p2; ---8

c, real, 0

nil

Exemplo

a: real; b: int; proc p1; c: real; ---end p1; proc p2; d: array[5] of int; proc p3; e,f: real; ---end p3; ---end p2; ---8

c, real, 0

a, real, 0

b, int, 8

p1,

p2,

d, array(5,int), 0

p3,

nil

Exemplo

a: real; b: int; proc p1; c: real; ---end p1; proc p2; d: array[5] of int; proc p3; e,f: real; ---end p3; ---end p2; ---8

c, real, 0

a, real, 0

b, int, 8

p1,

p2,

d, array(5,int), 0

p3,

16

e, real, 0

f, real, 8

nil

Exemplo

a: real; b: int; proc p1; c: real; ---end p1; proc p2; d: array[5] of int; proc p3; e,f: real; ---end p3; ---end p2; ---8

c, real, 0

a, real, 0

b, int, 8

p1,

p2,

24

d, array(5,int), 0

p3,

16

e, real, 0

f, real, 8

nil 20

Exemplo

a: real; b: int; proc p1; c: real; ---end p1; proc p2; d: array[5] of int; proc p3; e,f: real; ---end p3; ---end p2; ---8

c, real, 0

a, real, 0

b, int, 8

p1,

p2,

24

d, array(5,int), 0

p3,

16

e, real, 0

f, real, 8

(6)

TAC

• Geração de código de três endereços:

– Expressões

– Declarações (escopo simples)

– Declarações (escopos aninhados)

– Comandos de atribuição

– Arrays e Registros

– Expressões booleanas

– Comandos de decisão

– Comandos de iteração

Comandos de atribuição

S →id := E { p = lookup(id.nome);

if p <> NULL thenS.codigo = E.codigo || geracod (p “:=“ E.local) else erro}

E →E1+E2 {E.local = geratemp;

E.codigo = E1.codigo || E2.codigo || geracod (E.local “:=“ E1.local “+” E2.local) }

E →E1*E2 {E.local = geratemp;

E.codigo = E1.codigo || E2.codigo || geracod (E.local “:=“ E1.local “*” E2.local) }

E →-E1 {E.local = geratemp;

E.codigo = E1.codigo || geracod (E.local “:=“ “-u” E1.local) } E →E1 {E.local = E1.local;}

E →id { p=lookup(id.nome);

Referências

Documentos relacionados

mori foi realizada a análise da infecção causada por um isolado geográfico do BmNPV no Estado do Paraná, Brasil, sendo a espécie viral identificada como Bombyx mori

(2012), o qual comparou a TCC com exercícios de controle motor, mostrando que exercícios de controle motor e TCC têm efeitos semelhantes na redução da dor e

O paciente tem pelo menos 02 (dois) dos seguintes sinais e sintomas, sem nenhuma outra causa:. - febre (temperatura axilar &gt; 37,8 o C)

Proponha Proponha uma uma função função chamada chamada inicializa() inicializa() que receba um vetor de inteiros, seu que receba um vetor de inteiros, seu tamanho,

A variação é explicada principalmente pela estratégia da Companhia de reduzir o nível de financiamento com fornecedores (pela redução o prazo médio de pagamento) que,

Da Silva et al (2020) estudaram a variabilidade espacial do fator k em áreas comerciais de cana-de-açúcar, causadas pelas estruturas multivariadas de perdas de carbono em

Mais do que propor uma metodologia para a musicalização de adultos, esse trabalho deve fazer o leitor refletir sobre a prática do ensino musical atual vigente.. O que

Este trabalho é resultado de uma pesquisa quantitativa sobre a audiência realizada em 1999 envolvendo professores e alunos do Núcleo de Pesquisa de Comunicação da Universidade