1 / 45

CES-41 COMPILADORES

CES-41 COMPILADORES. Capítulo VII Código Intermediário. 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.

kylar
Download Presentation

CES-41 COMPILADORES

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


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

  2. Capítulo VIICó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:inti, fat; statements: if (n < 0 || 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 <= 0 || m > 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'); }

  5. Quádruplas do escopo global: 1) OPENMOD, (FUNCAO, ##global), (IDLE), (IDLE) 2) CALLOP, (FUNCAO, main), (INT, 0), (IDLE) 3) EXITOP, (IDLE) , (IDLE) , (IDLE) • A quádrupla OPENMOD aloca memória para as variáveis globais • A quádrupla CALLOP chama a função main, passando-lhe zero argumentos • A função main, como é do tipo void, não produz resultado • A função main, depois de executada, retorna o controle para o escopo global • A quádrupla EXITOPencerra a execução do programa

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

  7. do { - - - - - } while (c == 's'); 2) NOP, (IDLE), (IDLE), (IDLE) - - - - - 49) 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) - - - - - 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 <= 0 || m > 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) - - - - - 47) 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çãofat: int fat (int n) { local: int i, fat; - - - - - returnfat; } 1) OPENMOD, (FUNCAO, fat), (IDLE), (IDLE) - - - - - 22) RETURNOP, (VAR, fat), (IDLE), (IDLE) OPENMOD aloca na memória as variáveis locais da função fat 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 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

  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 < 0 || 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 um operando: • 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: void InicCodIntermed (void); voidInicCodIntermFunc (simbolo); voidImprimeQuadruplas (void); quadruplaGeraQuadrupla (int, operando, operando, operando); simboloNovaTemp (int);

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

  20. Função InicCodIntermFunc (simbolosimb): 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: • Comando do-while • Comando for • Comando case

  22. 7.3.1 – Quádruplas para o comando do-while Seja o seguinte trecho de programa: local: inti, 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 Suas possíveis quádruplas: 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)

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

  24. 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) 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; Possíveis quádruplas

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

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

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

  28. 7.3.3 – Quádruplas para o comando case Seja o seguinte trecho de programa: local: inti, 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; } - - - - - Aninhamento de dois comandos case A seguir possíveis quádruplas para ele

  29. case (i + j) 1, 2, 3: 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) 4, 5: { i = i + 1; j = j + 2; } Final do case externo

  30. 4, 5: 6: 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) { i = i + 3; j = j - 1; } Final do case externo

  31. 6: 7: 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) 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) case (i – j) 1, 2: 3: i = i * j Final do case interno

  32. 3: 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) 52) NOP, (IDLE), (IDLE), (IDLE) 53) JUMPOP, (IDLE), (IDLE), (ROTULO, 64) j = j + i; default vazio Final do case interno Final do case externo

  33. 7: 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) 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) 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 30 e quádrupla 32 • Quádruplas de desvio 35, 37 e quádrupla 39 • Quádrupla de desvio 45 e quádrupla 47 • Quádruplas de desvio 15, 27, 53 e quádrupla 64 • 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: • No 1o case: operando (VAR, ##1) nas quádruplas 3, 5, 7, 17, 19, 29 e 55 • No 2o 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 • 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, x, @y; statements: y := &x; x := #y + a; #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

  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 ListExpre 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 CallFuncpode ter o mesmo atributo que o não-terminal Variavel: %type <infovar> VariavelCallFunc • Onde: • E também: • 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. Mais um campo na TabSimb: um ponteiro para um funchead Na produção do não-terminal CallFunc: CallFunc : ID ABPAR { simb = ProcuraSimb ($1, escopo->escopo); $<simb>$ = simb;if (! simb) NaoDeclarado ($1); } Argumentos FPAR { $$.simb = $<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; } ;

  43. 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: CallMod : CALL CallFunc PVIRG ;

  44. 7.5.3 – Retorno de subprogramas • 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 • Isso é feito na produção do não terminal Cmds: Cmds : STATEMENTS ABCHAV ListCmds FCHAV { if (quadcorrente->oper != RETURNOP) GeraQuadrupla (RETURNOP, opndidle, opndidle, opndidle); - - - - - } ; • Lembrando o contexto do não-terminal Cmds: Modulo : CabecalhoDeclLocsCmds Garante que a última quádrupla de qualquer função é um RETURN Mesmo que a função tenha RETURN fora do final

More Related