A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

CES-41 COMPILADORES Capítulo VII Código Intermediário.

Apresentações semelhantes


Apresentação em tema: "CES-41 COMPILADORES Capítulo VII Código Intermediário."— Transcrição da apresentação:

1 CES-41 COMPILADORES Capítulo VII Código Intermediário

2 Capítulo VII Código Intermediário 7.1 – Um programa com subprogramas 7.2 – Estruturas de dados 7.3 – Quádruplas para alguns comandos 7.4 – Quádruplas para ponteiros 7.5 – Quádruplas para subprogramação

3 7.1 – Um Programa com Subprogramas global: int comb; functions: int fat (int n;) { local: int i, fat; statements: if (n 7) fat = ~1; else { fat = 1; i = 2; while (i <= n) { fat = fat * i; i = i + 1; } } return fat; } Seja o seguinte programa para calcular o número de combinações de m elementos tomados n a n:

4 void main () { local: char c; int m, n; statements: do { write ("Combinacao de m elementos tomados n a n? (s/n): "); do read (c); while (c!='s' && c!='n'); if (c == 's') { write ("m: "); read (m); write ("n: "); read (n); if (m 7 || n 7 || n <= 0 || m < n) write ("Dados incompativeis"); else { comb = fat(m) / (fat(m-n) * fat(n)); write ("Num. de combinacoes: ", comb); }} } while (c == 's'); }

6 Quádruplas da função main: Quádruplas da função main: void main () { local: char c; int m, n; } 1) OPENMOD, (FUNCAO, main), (IDLE), (IDLE) ) RETURNOP, (IDLE), (IDLE), (IDLE) OPENMOD aloca na memória as variáveis locais da função main Sendo main do tipo void, a quádrupla RETURNOP não tem operando para retornar RETURNOP: Desaloca da memória as variáveis locais da função main Retorna o controle da execução para o escopo global

7 do { } while (c == 's'); 2) NOP, (IDLE), (IDLE), (IDLE) ) EQOP, (VAR, c), (CHAR, s), (VAR, ##25) 50) JTOP, (VAR, ##25), (IDLE), (ROTULO, 2) write ("Combinacao de m elementos tomados n a n? (s/n): "); 3) PARAM, (CADEIA, Combinacao de m elementos tomados n a n? (s/n): ), (IDLE), (IDLE) 4) WRITEOP, (INT, 1), (IDLE), (IDLE)

8 do read (c); while (c!='s' && c!='n'); 5) NOP, (IDLE), (IDLE), (IDLE) 6) PARAM, (VAR, c), (IDLE), (IDLE) 7) READOP, (INT, 1), (IDLE), (IDLE) 8) NEOP, (VAR, c), (CHAR, s), (VAR, ##8) 9) NEOP, (VAR, c), (CHAR, n), (VAR, ##9) 10) ANDOP, (VAR, ##8), (VAR, ##9), (VAR, ##10) 11) JTOP, (VAR, ##10), (IDLE), (ROTULO, 5) if (c == 's') { } 12) EQOP, (VAR, c), (CHAR, s), (VAR, ##11) 13) JFOP, (VAR, ##11), (IDLE), (ROTULO, 48) ) NOP, (IDLE), (IDLE), (IDLE)

9 write ("m: "); read (m); write ("n: "); read (n); 14) PARAM, (CADEIA, m: ), (IDLE), (IDLE) 15) WRITEOP, (INT, 1), (IDLE), (IDLE) 16) PARAM, (VAR, m), (IDLE), (IDLE) 17) READOP, (INT, 1), (IDLE), (IDLE) 18) PARAM, (CADEIA, n: ), (IDLE), (IDLE) 19) WRITEOP, (INT, 1), (IDLE), (IDLE) 20) PARAM, (VAR, n), (IDLE), (IDLE) 21) READOP, (INT, 1), (IDLE), (IDLE)

10 if (m 7 || n 7 || n <= 0 || m < n) write ("Dados incompativeis"); else { } 22) LEOP, (VAR, m), (INT, 0), (VAR, ##12) 23) GTOP, (VAR, m), (INT, 7), (VAR, ##13) 24) OROP, (VAR, ##12), (VAR, ##13), (VAR, ##14) 25) LEOP, (VAR, n), (INT, 0), (VAR, ##15) 26) OROP, (VAR, ##14), (VAR, ##15), (VAR, ##16) 27) LTOP, (VAR, m), (VAR, n), (VAR, ##17) 28) OROP, (VAR, ##16), (VAR, ##17), (VAR, ##18) 29) JFOP, (VAR, ##18), (IDLE), (ROTULO, 33) 30) PARAM, (CADEIA, Dados incompativeis), (IDLE), (IDLE) 31) WRITEOP, (INT, 1), (IDLE), (IDLE) 32) JUMPOP, (IDLE), (IDLE), (ROTULO, 47) 33) NOP, (IDLE), (IDLE), (IDLE) ) NOP, (IDLE), (IDLE), (IDLE)

11 comb = fat(m) / (fat(m-n) * fat(n)); 34) PARAM, (VAR, m), (IDLE), (IDLE) 35) CALLOP, (FUNCAO, fat), (INT, 1), (VAR, ##19) 36) MENOSOP, (VAR, m), (VAR, n), (VAR, ##20) 37) PARAM, (VAR, ##20), (IDLE), (IDLE) 38) CALLOP, (FUNCAO, fat), (INT, 1), (VAR, ##21) 39) PARAM, (VAR, n), (IDLE), (IDLE) 40) CALLOP, (FUNCAO, fat), (INT, 1), (VAR, ##22) 41) MULTOP, (VAR, ##21), (VAR, ##22), (VAR, ##23) 42) DIVOP, (VAR, ##19), (VAR, ##23), (VAR, ##24) 43) ATRIBOP, (VAR, ##24), (IDLE), (VAR, comb) write ("Num. de combinacoes: ", comb); 44) PARAM, (CADEIA, Num. de combinacoes: ), (IDLE), (IDLE) 45) PARAM, (VAR, comb), (IDLE), (IDLE) 46) WRITEOP, (INT, 2), (IDLE), (IDLE)

12 34) PARAM, (VAR, m), (IDLE), (IDLE) 35) CALLOP, (FUNCAO, fat), (INT, 1), (VAR, ##19) 36) MENOSOP, (VAR, m), (VAR, n), (VAR, ##20) 37) PARAM, (VAR, ##20), (IDLE), (IDLE) 38) CALLOP, (FUNCAO, fat), (INT, 1), (VAR, ##21) 39) PARAM, (VAR, n), (IDLE), (IDLE) 40) CALLOP, (FUNCAO, fat), (INT, 1), (VAR, ##22) 41) MULTOP, (VAR, ##21), (VAR, ##22), (VAR, ##23) 42) DIVOP, (VAR, ##19), (VAR, ##23), (VAR, ##24) 43) ATRIBOP, (VAR, ##24), (IDLE), (VAR, comb) CALLOP chama a função fat Retira 1 argumento da pilha de parâmetros Deposita o argumento no parâmetro n da função fat O parâmetro n da função fat é localizado na lista de parâmetros do identificador fat na TabSmb

13 34) PARAM, (VAR, m), (IDLE), (IDLE) 35) CALLOP, (FUNCAO, fat), (INT, 1), (VAR, ##19) 36) MENOSOP, (VAR, m), (VAR, n), (VAR, ##20) 37) PARAM, (VAR, ##20), (IDLE), (IDLE) 38) CALLOP, (FUNCAO, fat), (INT, 1), (VAR, ##21) 39) PARAM, (VAR, n), (IDLE), (IDLE) 40) CALLOP, (FUNCAO, fat), (INT, 1), (VAR, ##22) 41) MULTOP, (VAR, ##21), (VAR, ##22), (VAR, ##23) 42) DIVOP, (VAR, ##19), (VAR, ##23), (VAR, ##24) 43) ATRIBOP, (VAR, ##24), (IDLE), (VAR, comb) Pela TabSimb, a função fat é do tipo int Ela deve retornar um valor no 3º operando da quádrupla ##19, ##21 e ##22 são novas temporárias para guardar o valor retornado de suas respectivas chamadas Essas temporárias de retorno são usadas para o cálculo de comb Como pode haver chamadas embutidas de funções, as temporárias de retorno devem ser introduzidas numa pilha

14 Quádruplas da função fat: Quádruplas da função fat: int fat (int n) { local: int i, fat; return fat; } 1) OPENMOD, (FUNCAO, fat), (IDLE), (IDLE) ) RETURNOP, (VAR, fat), (IDLE), (IDLE) OPENMOD aloca na memória as variáveis locais da função fat Pela TabSimb, a função fat do tipo int Então, RETURNOP deve retirar da pilha de variáveis de retorno uma para guardar o valor a ser retornado Essa variável deve ter sido empilhada pela função que a chamou RETURNOP: Desaloca da memória as variáveis locais e os parâmetros da função fat Retorna o controle da execução para a função main

15 2) LTOP, (VAR, n), (INT, 0), (VAR, ##1) 3) GTOP, (VAR, n), (INT, 7), (VAR, ##2) 4) OROP, (VAR, ##1), (VAR, ##2), (VAR, ##3) 5) JFOP, (VAR, ##3), (IDLE), (ROTULO, 9) 6) MENUNOP, (INT, 1), (IDLE), (VAR, ##4) 7) ATRIBOP, (VAR, ##4), (IDLE), (VAR, fat) 8) JUMPOP, (IDLE), (IDLE), (ROTULO, 21) 9) NOP, (IDLE), (IDLE), (IDLE) 10) ATRIBOP, (INT, 1), (IDLE), (VAR, fat) 11) ATRIBOP, (INT, 2), (IDLE), (VAR, i) 12) NOP, (IDLE), (IDLE), (IDLE) 13) LEOP, (VAR, i), (VAR, n), (VAR, ##5) 14) JFOP, (VAR, ##5), (IDLE), (ROTULO, 20) 15) MULTOP, (VAR, fat), (VAR, i), (VAR, ##6) 16) ATRIBOP, (VAR, ##6), (IDLE), (VAR, fat) 17) MAISOP, (VAR, i), (INT, 1), (VAR, ##7) 18) ATRIBOP, (VAR, ##7), (IDLE), (VAR, i) 19) JUMPOP, (IDLE), (IDLE), (ROTULO, 12) 20) NOP, (IDLE), (IDLE), (IDLE) 21) NOP, (IDLE), (IDLE), (IDLE) if (n 7) fat = ~1; else { fat = 1; i = 2; while (i <= n) { fat = fat * i; i = i + 1; }

16 7.2 – Estruturas de Dados As listas de quádruplas de cada subprograma:

17 Estrutura de uma quádrupla: Estrutura de uma quádrupla: Estrutura de um operando: Estrutura de um operando: Estrutura de um cabeçalho Estrutura de um cabeçalho de função (funchead): As declarações foram vistas no lab

18 Protótipos das funções para construir o código intermediário: Protótipos das funções para construir o código intermediário: void InicCodIntermed (void); void InicCodIntermFunc (simbolo); void ImprimeQuadruplas (void); quadrupla GeraQuadrupla (int, operando, operando, operando); simbolo NovaTemp (int);

19 Função InicCodIntermed: inicializa a estrutura do código intermediário, deixando-a assim: Função InicCodIntermed: inicializa a estrutura do código intermediário, deixando-a assim:

20 Função InicCodIntermFunc (simbolo simb): inicializa o código intermediário da função cujo nome está na tabela de símbolos apontada por simb; Função InicCodIntermFunc (simbolo simb): inicializa o código intermediário da função cujo nome está na tabela de símbolos apontada por simb; Deixa a estrutura do código intermediário assim:

21 7.3 – Quádruplas para Alguns Comandos Apresentada a seguir, programação para construir o código intermediário de comandos não abordados nas aulas de laboratório: Apresentada a seguir, programação para construir o código intermediário de comandos não abordados nas aulas de laboratório: Comando do-while Comando do-while Comando for Comando for Comando case Comando case

22 7.3.1 – Quádruplas para o comando do-while Seja o seguinte trecho de programa: local: int i, j, h; statements: do {i = i + h; j = j - h; } while (i < j); i = 0; A programação para isso está na produção do não terminal CmdDo a seguir A programação para isso está na produção do não terminal CmdDo a seguir 2) NOP, (IDLE), (IDLE), (IDLE) 3) MAISOP, (VAR, i), (VAR, h), (VAR, ##1) 4) ATRIBOP, (VAR, ##1), (IDLE), (VAR, i) 5) MENOSOP, (VAR, j), (VAR, h), (VAR, ##2) 6) ATRIBOP, (VAR, ##2), (IDLE), (VAR, j) 7) LTOP, (VAR, i), (VAR, j), (VAR, ##3) 8) JTOP, (VAR, ##3), (IDLE), (ROTULO, 2) 9) ATRIBOP, (INT, 0), (IDLE), (VAR, i) Suas possíveis quádruplas:

23 CmdDo: DO { $ $ = GeraQuadrupla (NOP, opndidle, opndidle, opndidle); } Comando WHILE ABPAR Expressao { opndaux.tipo = ROTOPND; opndaux.atr.rotulo = $ 2; GeraQuadrupla (JTOP, $6.opnd, opndidle, opndaux); } FPAR PVIRG ; Comando JTOP##n---- ROT Expressão NOP ##n $2

24 7.3.2 – Quádruplas para o comando for Seja o seguinte trecho de programa: local: int i, n, s, p; statements: s = 0; p = 1; for (i = 1; i <= n; i = i + 1) { s = s + i; p = p * i; } i = 0; i = 0; 2) ATRIBOP, (INT, 0), (IDLE), (VAR, s) 3) ATRIBOP, (INT, 1), (IDLE), (VAR, p) 4) ATRIBOP, (INT, 1), (IDLE), (VAR, i) 5) NOP, (IDLE), (IDLE), (IDLE) 6) LEOP, (VAR, i), (VAR, n), (VAR, ##1) 7) JFOP, (VAR, ##1), (IDLE), (ROTULO, 17) 8) NOP, (IDLE), (IDLE), (IDLE) 9) MAISOP, (VAR, s), (VAR, i), (VAR, ##3) 10) ATRIBOP, (VAR, ##3), (IDLE), (VAR, s) 11) MULTOP, (VAR, p), (VAR, i), (VAR, ##4) 12) ATRIBOP, (VAR, ##4), (IDLE), (VAR, p) 13) NOP, (IDLE), (IDLE), (IDLE) 14) MAISOP, (VAR, i), (INT, 1), (VAR, ##2) 15) ATRIBOP, (VAR, ##2), (IDLE), (VAR, i) 16) JUMPOP, (IDLE), (IDLE), (ROTULO, 5) 17) NOP, (IDLE), (IDLE), (IDLE) 18) ATRIBOP, (INT, 0), (IDLE), (VAR, i) Possíveis quádruplas

25 CmdFor:FOR ABPAR CmdAtrib PVIRG { $ $ = GeraQuadrupla (NOP, opndidle, opndidle, opndidle); } Expressao { opndaux.tipo = ROTOPND; $ $ = GeraQuadrupla (JFOP, $6.opnd, opndidle, opndaux); } PVIRG { $ $ = GeraQuadrupla (NOP, opndidle, opndidle, opndidle); } CmdAtrib FPAR { $ $ = quadcorrente; } { $ $ = GeraQuadrupla (NOP, opndidle, opndidle, opndidle); } Comando { quadaux = quadcorrente; opndaux.tipo = ROTOPND; opndaux.atr.rotulo = $ 5; quadaux2 = GeraQuadrupla (JUMPOP, opndidle, opndidle, opndaux); $ 7->result.atr.rotulo = GeraQuadrupla (NOP, opndidle, opndidle, opndidle); Correcao da ordem das quadruplas } ; A ordem das quádruplas deve ser corrigida

26 Ordem na qual as quádruplas foram geradas: Comando deve ser executado antes de CmdAtrib2 CmdAtrib 1 NOP Expressão JFOP, ##expr, ---, rot NOP CmdAtrib 2 $5 $7 $9 $12 NOP Comando JUMP, ---, ---, rot NOP $13 quadaux quadaux2

27 CmdAtrib 1 NOP Expressão JFOP, ##expr, ---, rot NOP CmdAtrib 2Comando JUMP, ---, ---, rot NOP $5 $7 $9 $12 $13 quadaux quadaux2 Agora Comando será executado antes de CmdAtrib2 Correção da ordem das quádruplas: $ 7->prox = $ 13; quadaux->prox = $ 9; $ 12->prox = quadaux2; RenumQuadruplas ($ 7, quadcorrente);

28 7.3.3 – Quádruplas para o comando case Seja o seguinte trecho de programa: local: int i, n, s; statements: case (i + j) { 1, 2, 3: {i = i + 1; j = j + 2;} 4, 5: {i = i + 3; j = j - 1;} 6: case (i - j) { 1, 2: i = i * j; 3: j = j + i; } 7: j = i - j; default: i = 0; default: i = 0;} Aninhamento de dois comandos case A seguir possíveis quádruplas para ele

29 2) MAISOP, (VAR, i), (VAR, j), (VAR, ##1) 3) EQOP, (VAR, ##1), (INT, 1), (VAR, ##2) 4) JTOP, (VAR, ##2), (IDLE), (ROTULO, 10) 5) EQOP, (VAR, ##1), (INT, 2), (VAR, ##3) 6) JTOP, (VAR, ##3), (IDLE), (ROTULO, 10) 7) EQOP, (VAR, ##1), (INT, 3), (VAR, ##4) 8) JTOP, (VAR, ##4), (IDLE), (ROTULO, 10) 9) JUMPOP, (IDLE), (IDLE), (ROTULO, 16) 10) NOP, (IDLE), (IDLE), (IDLE) 11) MAISOP, (VAR, i), (INT, 1), (VAR, ##5) 12) ATRIBOP, (VAR, ##5), (IDLE), (VAR, i) 13) MAISOP, (VAR, j), (INT, 2), (VAR, ##6) 14) ATRIBOP, (VAR, ##6), (IDLE), (VAR, j) 15) JUMPOP, (IDLE), (IDLE), (ROTULO, 64) case (i + j) 1, 2, 3: { i = i + 1; j = j + 2; } Final do case externo 4, 5:

30 16) NOP, (IDLE), (IDLE), (IDLE) 17) EQOP, (VAR, ##1), (INT, 4), (VAR, ##7) 18) JTOP, (VAR, ##7), (IDLE), (ROTULO, 22) 19) EQOP, (VAR, ##1), (INT, 5), (VAR, ##8) 20) JTOP, (VAR, ##8), (IDLE), (ROTULO, 22) 21) JUMPOP, (IDLE), (IDLE), (ROTULO, 28) 22) NOP, (IDLE), (IDLE), (IDLE) 23) MAISOP, (VAR, i), (INT, 3), (VAR, ##9) 24) ATRIBOP, (VAR, ##9), (IDLE), (VAR, i) 25) MENOSOP, (VAR, j), (INT, 1), (VAR, ##10) 26) ATRIBOP, (VAR, ##10), (IDLE), (VAR, j) 27) JUMPOP, (IDLE), (IDLE), (ROTULO, 64) 4, 5: { i = i + 3; j = j - 1; } Final do case externo 6:

31 28) NOP, (IDLE), (IDLE), (IDLE) 29) EQOP, (VAR, ##1), (INT, 6), (VAR, ##11) 30) JTOP, (VAR, ##11), (IDLE), (ROTULO, 32) 31) JUMPOP, (IDLE), (IDLE), (ROTULO, 54) 32) NOP, (IDLE), (IDLE), (IDLE) 33) MENOSOP, (VAR, i), (VAR, j), (VAR, ##12) 33) MENOSOP, (VAR, i), (VAR, j), (VAR, ##12) 34) EQOP, (VAR, ##12), (INT, 1), (VAR, ##13) 35) JTOP, (VAR, ##13), (IDLE), (ROTULO, 39) 36) EQOP, (VAR, ##12), (INT, 2), (VAR, ##14) 37) JTOP, (VAR, ##14), (IDLE), (ROTULO, 39) 38) JUMPOP, (IDLE), (IDLE), (ROTULO, 43) 39) NOP, (IDLE), (IDLE), (IDLE) 40) MULTOP, (VAR, i), (VAR, j), (VAR, ##15) 41) ATRIBOP, (VAR, ##15), (IDLE), (VAR, i) 42) JUMPOP, (IDLE), (IDLE), (ROTULO, 52) 6: i = i * j Final do case interno case (i – j) 1, 2: 3: 7:

32 43) NOP, (IDLE), (IDLE), (IDLE) 44) EQOP, (VAR, ##12), (INT, 3), (VAR, ##16) 45) JTOP, (VAR, ##16), (IDLE), (ROTULO, 47) 46) JUMPOP, (IDLE), (IDLE), (ROTULO, 51) 47) NOP, (IDLE), (IDLE), (IDLE) 48) MAISOP, (VAR, j), (VAR, i), (VAR, ##17) 49) ATRIBOP, (VAR, ##17), (IDLE), (VAR, j) 50) JUMPOP, (IDLE), (IDLE), (ROTULO, 52) 51) NOP, (IDLE), (IDLE), (IDLE) 51) NOP, (IDLE), (IDLE), (IDLE) 52) NOP, (IDLE), (IDLE), (IDLE) 53) JUMPOP, (IDLE), (IDLE), (ROTULO, 64) 3: Final do case externo j = j + i; default vazio Final do case interno

33 54) NOP, (IDLE), (IDLE), (IDLE) 55) EQOP, (VAR, ##1), (INT, 7), (VAR, ##18) 56) JTOP, (VAR, ##18), (IDLE), (ROTULO, 58) 57) JUMPOP, (IDLE), (IDLE), (ROTULO, 62) 57) JUMPOP, (IDLE), (IDLE), (ROTULO, 62) 58) NOP, (IDLE), (IDLE), (IDLE) 59) MENOSOP, (VAR, i), (VAR, j), (VAR, ##19) 60) ATRIBOP, (VAR, ##19), (IDLE), (VAR, j) 61) JUMPOP, (IDLE), (IDLE), (ROTULO, 64) 62) NOP, (IDLE), (IDLE), (IDLE) 63) ATRIBOP, (INT, 0), (IDLE), (VAR, i) 64) NOP, (IDLE), (IDLE), (IDLE) 7: j = j + i; default: i = 0; Final do case externo

34 Nesse exemplo, observa-se que o rótulo das quádruplas de desvio 4, 6, e 8 somente serão preenchidos, quando a quádrupla 10 for gerada; o mesmo vale para: Quádruplas de desvio 18, 20 e quádrupla 22 Quádruplas de desvio 18, 20 e quádrupla 22 Quádruplas de desvio 30 e quádrupla 32 Quádruplas de desvio 30 e quádrupla 32 Quádruplas de desvio 35, 37 e quádrupla 39 Quádruplas de desvio 35, 37 e quádrupla 39 Quádrupla de desvio 45 e quádrupla 47 Quádrupla de desvio 45 e quádrupla 47 Quádruplas de desvio 15, 27, 53 e quádrupla 64 Quádruplas de desvio 15, 27, 53 e quádrupla 64 Quádruplas de desvio 42, 50 e quádrupla 52 Quádruplas de desvio 42, 50 e quádrupla 52 Para esse preenchimento, essas quádruplas podem ser colocadas numa lista de quádruplas a fazer parte do atributo dos não-terminais da formação do comando case Quando a quádrupla destino dos desvios for gerada, tais rótulos serão preenchidos

35 Observa-se também que o resultado da expressão central do case será o primeiro operando de várias quádruplas: Observa-se também que o resultado da expressão central do case será o primeiro operando de várias quádruplas: No 1 o case: operando (VAR, ##1) nas quádruplas 3, 5, 7, 17, 19, 29 e 55 No 1 o case: operando (VAR, ##1) nas quádruplas 3, 5, 7, 17, 19, 29 e 55 No 2 o case: operando (VAR, ##12) nas quádruplas 34, 36 e 44 No 2 o case: operando (VAR, ##12) nas quádruplas 34, 36 e 44 É conveniente que esses operandos sejam colocados numa pilha apropriada, no momento em que a expressão central de seu case é analisada, e sejam dela retirados no final da análise do seu case É conveniente que esses operandos sejam colocados numa pilha apropriada, no momento em que a expressão central de seu case é analisada, e sejam dela retirados no final da análise do seu case As estruturas para tais listas de quádruplas e tal pilha de operandos bem como as declarações e programação para a geração de quádruplas para comandos case ficam como exercício As estruturas para tais listas de quádruplas e tal pilha de operandos bem como as declarações e programação para a geração de quádruplas para comandos case ficam como exercício

36 7.4 – Quádruplas para Ponteiros Seja o seguinte trecho de programa: local: int a, b, statements: y := &x; x := #y + a; #y := a + b; #y := a + b; Suas possíveis quádruplas: 2) ENDEROP, (VAR, x), (IDLE), (VAR, ##1) 3) ATRIBOP, (VAR, ##1), (IDLE), (VAR, y) 4) CONTAPONT, (VAR, y), (IDLE), (VAR, ##2) 5) MAISOP, (VAR, ##2), (VAR, a), (VAR, ##3) 6) ATRIBOP, (VAR, ##3), (IDLE), (VAR, x) 7) MAISOP, (VAR, a), (VAR, b), (VAR, ##4) 8) ATRIBPONT, (VAR, ##4), (IDLE), (VAR, y)

37 Produções para referências a ponteiros: Fator: Variavel | CTINT | CTREAL | CTCHAR | TRUE | FALSE | ~ Fator | ( Expressao ) |CallFunc | # Variavel CmdAtrib:LadoEsquerdo := Expressao ; |LadoEsquerdo := & Variavel ; LadoEsquerdo:Variavel | # Variavel A programação para a geração de quádruplas envolvendo ponteiros fica como exercício A programação para a geração de quádruplas envolvendo ponteiros fica como exercício

38 7.5 – Quádruplas para Subprogramação Produções envolvidas: Comando: CallMod CallMod: CALL CallFunc PVIRG CallFunc: ID ABPAR Argumentos FPAR Argumentos: | ListExpr ListExpr: Expressao | ListExpr VIRG Expressao CmdReturn: RETURN PVIRG | RETURN Expressao PVIRG Fator: CallFunc

39 7.5.1 – Chamada de subprogramas Exemplo: na função main do programa inicial, o comando comb = fat(m) / (fat(m-n) * fat(n)); tem as seguintes quádruplas: 34) PARAM, (VAR, m), (IDLE), (IDLE) 35) CALLOP, (FUNCAO, fat), (INT, 1), (VAR, ##19) 36) MENOSOP, (VAR, m), (VAR, n), (VAR, ##20) 37) PARAM, (VAR, ##20), (IDLE), (IDLE) 38) CALLOP, (FUNCAO, fat), (INT, 1), (VAR, ##21) 39) PARAM, (VAR, n), (IDLE), (IDLE) 40) CALLOP, (FUNCAO, fat), (INT, 1), (VAR, ##22) 41) MULTOP, (VAR, ##21), (VAR, ##22), (VAR, ##23) 42) DIVOP, (VAR, ##19), (VAR, ##23), (VAR, ##24) 43) ATRIBOP, (VAR, ##24), (IDLE), (VAR, comb)

40 Nas produções dos não-terminais ListExpr e Argumentos: ListExpr : Expressao { $$.nargs = 1; $$.listtipo = InicListTipo ($1.tipo); GeraQuadrupla (PARAM, $1.opnd, opndidle, opndidle); } | ListExpr VIRG Expressao { $$.narg = $1.narg + 1; $$.listtipo = ConcatListTipo ($1.listtipo, InicListTipo ($3.tipo)); GeraQuadrupla (PARAM, $3.opnd, opndidle, opndidle); }; Argumentos: {$$.nargs = 0; $$.listtipo = NULL;} | ListExpr /* default: $$ = $1; */

41 O não-terminal CallFunc pode ter o mesmo atributo que o não-terminal Variavel: O não-terminal CallFunc pode ter o mesmo atributo que o não-terminal Variavel: %type Variavel CallFunc Onde: Onde: E também: E também: Então o atributo de CallFunc tem dois campos: Então o atributo de CallFunc tem dois campos: simb e opnd %union { infovariavel infovar; } typedef struct infovariavel infovariavel; struct infovariavel { simbolo simb; operando opnd; };

42 Na produção do não-terminal CallFunc: CallFunc: ID ABPAR { simb = ProcuraSimb ($1, escopo->escopo); $ $ = simb; if (! simb) NaoDeclarado ($1); } Argumentos FPAR { $$.simb = $ 3; Testes de compatibilidade opnd1.tipo = FUNCOPND; opnd1.atr.func = $$.simb->fhead; opnd2.tipo = INTOPND; opnd2.atr.valint = $4.nargs; if ($$.simb->tvar == NAOVAR) result = opndidle; else { result.tipo = VAROPND; result.atr.simb = NovaTemp ($$.simb->tvar); } GeraQuadrupla (CALLOP, opnd1, opnd2, result); $$.opnd = result; } ; Mais um campo na TabSimb: um ponteiro para um funchead

43 Na produção do não-terminal Fator: Na produção do não-terminal Fator: Fator: CallFunc { if ($1.simb != NULL) { $$.tipo = $1.simb->tvar; $$.opnd = $1.opnd; }}; Não há programação especial para a produção: Não há programação especial para a produção: CallMod: CALL CallFunc PVIRG ; CallMod: CALL CallFunc PVIRG ;

44 7.5.3 – Retorno de subprogramas Nas produções do não-terminal CmdReturn Nas produções do não-terminal CmdReturn CmdReturn:RETURN { GeraQuadrupla (RETURNOP, opndidle, opndidle, opndidle); } |RETURN Expressao { GeraQuadrupla (RETURNOP, $2.opnd, opndidle, opndidle); };

45 Para o caso de uma função não ter retorno explícito, deve-se gerar uma quádrupla com a operação de retornar Para o caso de uma função não ter retorno explícito, deve-se gerar uma quádrupla com a operação de retornar Isso é feito na produção do não terminal Cmds: Isso é feito na produção do não terminal Cmds: Cmds: STATEMENTS ABCHAV ListCmds FCHAV { if (quadcorrente->oper != RETURNOP) GeraQuadrupla (RETURNOP, opndidle, opndidle, opndidle); GeraQuadrupla (RETURNOP, opndidle, opndidle, opndidle); }; Lembrando o contexto do não-terminal Cmds: Lembrando o contexto do não-terminal Cmds: Modulo: Cabecalho DeclLocs Cmds Garante que a última quádrupla de qualquer função é um RETURN Mesmo que a função tenha RETURN fora do final


Carregar ppt "CES-41 COMPILADORES Capítulo VII Código Intermediário."

Apresentações semelhantes


Anúncios Google