CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

79
CES-41 COMPILADORES CES-41 COMPILADORES Aulas Práticas - 2013 Aulas Práticas - 2013 Capítulo IV Capítulo IV Código Intermediário Código Intermediário no Yacc no Yacc

Transcript of CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Page 1: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

CES-41 CES-41 COMPILADORESCOMPILADORES

Aulas Práticas - 2013Aulas Práticas - 2013

Capítulo IV Capítulo IV

Código Intermediário Código Intermediário no Yaccno Yacc

Page 2: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

O sub-set da Linguagem O sub-set da Linguagem COMP-ITA-2013COMP-ITA-2013, , usado no final do capítulo anterior, contém:usado no final do capítulo anterior, contém:

Comandos de atribuição, compostos, Comandos de atribuição, compostos, entrada e saída, condicionais, enquanto, entrada e saída, condicionais, enquanto, variáveis escalares e indexadasvariáveis escalares e indexadas

Seja essa linguagem chamada de Seja essa linguagem chamada de Sub-Set2 Sub-Set2 20132013

Seja o programa a seguir, escrito em Seja o programa a seguir, escrito em Sub-Set2 Sub-Set2 20132013, para encontrar números primos, para encontrar números primos

Page 3: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

programa primos;programa primos;var logic achou; int n, div, resto, cont, num;var logic achou; int n, div, resto, cont, num;{{

ler (n);ler (n); escrever (n, " primeiros numeros naturais primos:\n\n");escrever (n, " primeiros numeros naturais primos:\n\n");

se (n > 0) {se (n > 0) {num := 1; cont := 0;num := 1; cont := 0;enquanto (cont < n) {enquanto (cont < n) {

num := num + 1; div := 2; achou := falso;num := num + 1; div := 2; achou := falso;enquanto (achou = falso && div * div <= num) {enquanto (achou = falso && div * div <= num) {

resto := num % div;resto := num % div;se (resto = 0) achou := verdade;se (resto = 0) achou := verdade;senao div := div + 1;senao div := div + 1;

}}se (achou = falso) {se (achou = falso) {

escrever (num, "\n"); cont := cont + 1;escrever (num, "\n"); cont := cont + 1;}}

} } }}

senao escrever ("O valor de entrada deveria ser maior que senao escrever ("O valor de entrada deveria ser maior que zero");zero");

}}

Page 4: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Um possível código intermediário não Um possível código intermediário não otimizado:otimizado:

programa primos;programa primos;var logic achou; int n, div, resto, cont, num;var logic achou; int n, div, resto, cont, num;

1) OPENMOD, (MODULO, primos), (IDLE), (IDLE)1) OPENMOD, (MODULO, primos), (IDLE), (IDLE)

ler (n);ler (n);

2) PARAM, (VAR, n), (IDLE), (IDLE)2) PARAM, (VAR, n), (IDLE), (IDLE)

3) 3) READ, (INT, 1), (IDLE), (IDLE)READ, (INT, 1), (IDLE), (IDLE)

Page 5: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

se (n > 0) {se (n > 0) {

- - - - -- - - - -

}}

4) GT, (VAR, n), (INT, 0), (VAR, ##1)4) GT, (VAR, n), (INT, 0), (VAR, ##1)

5) JF, (VAR, ##1), (IDLE), (ROTULO, 42)5) JF, (VAR, ##1), (IDLE), (ROTULO, 42)

- - - - -- - - - -

42) NOP, (IDLE), (IDLE), (IDLE)42) NOP, (IDLE), (IDLE), (IDLE)

num := 0; cont := 0;num := 0; cont := 0;

6) ATRIB, (INT, 0), (IDLE), (VAR, num)6) ATRIB, (INT, 0), (IDLE), (VAR, num)

7) ATRIB, (INT, 0), (IDLE), (VAR, cont)7) ATRIB, (INT, 0), (IDLE), (VAR, cont)

NOP: no operation

Todos os desvios serão feitos para quádruplas com NOP’s

Facilitam a programação

Devem ser eliminadas na fase de otimização

Page 6: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

enquanto (cont < n) {enquanto (cont < n) {

- - - - -- - - - -

}}

8) NOP, (IDLE), (IDLE), (IDLE)8) NOP, (IDLE), (IDLE), (IDLE)

9) LT, (VAR, cont), (VAR, n), (VAR, ##2)9) LT, (VAR, cont), (VAR, n), (VAR, ##2)

10) JF, (VAR, ##2), (IDLE), (ROTULO, 41)10) JF, (VAR, ##2), (IDLE), (ROTULO, 41)

- - - - -- - - - -

40) JUMP, (IDLE), (IDLE), (ROTULO, 8)40) JUMP, (IDLE), (IDLE), (ROTULO, 8)

41) NOP, (IDLE), (IDLE), (IDLE)41) NOP, (IDLE), (IDLE), (IDLE)

num := num + 1; div := 2; achou := falso;num := num + 1; div := 2; achou := falso;

11) MAIS, (VAR, num), (INT, 1), (VAR, ##3)11) MAIS, (VAR, num), (INT, 1), (VAR, ##3)

12) ATRIB, (VAR, ##3), (IDLE), (VAR, num)12) ATRIB, (VAR, ##3), (IDLE), (VAR, num)

13) ATRIB, (INT, 2), (IDLE), (VAR, div)13) ATRIB, (INT, 2), (IDLE), (VAR, div)

14) ATRIB, (LOGIC, 0), (IDLE), (VAR, achou)14) ATRIB, (LOGIC, 0), (IDLE), (VAR, achou)

NOP: no operation

Todos os desvios serão feitos para quádruplas com NOP’s

Facilitam a programação

Devem ser eliminadas na fase de otimização

Page 7: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

enquanto (achou = falso && div * div <= num) {enquanto (achou = falso && div * div <= num) {

- - - - -- - - - -

}}

15) NOP, (IDLE), (IDLE), (IDLE)15) NOP, (IDLE), (IDLE), (IDLE)

16) EQ, (VAR, achou), (LOGIC, 0), (VAR, ##4)16) EQ, (VAR, achou), (LOGIC, 0), (VAR, ##4)

17) MULT, (VAR, div), (VAR, div), (VAR, ##5)17) MULT, (VAR, div), (VAR, div), (VAR, ##5)

18) LE, (VAR, ##5), (VAR, num), (VAR, ##6)18) LE, (VAR, ##5), (VAR, num), (VAR, ##6)

19) AND, (VAR, ##4), (VAR, ##6), (VAR, ##7)19) AND, (VAR, ##4), (VAR, ##6), (VAR, ##7)

20) JF, (VAR, ##7), (IDLE), (ROTULO, 32)20) JF, (VAR, ##7), (IDLE), (ROTULO, 32)

- - - - -- - - - -

31) JUMP, (IDLE), (IDLE), (ROTULO, 15)31) JUMP, (IDLE), (IDLE), (ROTULO, 15)

32) NOP, (IDLE), (IDLE), (IDLE)32) NOP, (IDLE), (IDLE), (IDLE)

Page 8: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

resto := num % div;resto := num % div;se (resto = 0) achou := verdade;se (resto = 0) achou := verdade;senao div := div + 1;senao div := div + 1;

21) RESTO, (VAR, num), (VAR, div), (VAR, ##8)21) RESTO, (VAR, num), (VAR, div), (VAR, ##8)

22) ATRIB, (VAR, ##8), (IDLE), (VAR, resto)22) ATRIB, (VAR, ##8), (IDLE), (VAR, resto)

23) EQ, (VAR, resto), (INT, 0), (VAR, ##9)23) EQ, (VAR, resto), (INT, 0), (VAR, ##9)

24) JF, (VAR, ##9), (IDLE), (ROTULO, 27)24) JF, (VAR, ##9), (IDLE), (ROTULO, 27)

25) ATRIB, (LOGIC, 1), (IDLE), (VAR, achou)25) ATRIB, (LOGIC, 1), (IDLE), (VAR, achou)

26) JUMP, (IDLE), (IDLE), (ROTULO, 30)26) JUMP, (IDLE), (IDLE), (ROTULO, 30)

27) NOP, (IDLE), (IDLE), (IDLE)27) NOP, (IDLE), (IDLE), (IDLE)

28) MAIS, (VAR, div), (INT, 1), (VAR, ##10)28) MAIS, (VAR, div), (INT, 1), (VAR, ##10)

29) ATRIB, (VAR, ##10), (IDLE), (VAR, div)29) ATRIB, (VAR, ##10), (IDLE), (VAR, div)

30) NOP, (IDLE), (IDLE), (IDLE)30) NOP, (IDLE), (IDLE), (IDLE)

Page 9: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

se (achou = falso) {escrever (num); cont := cont + se (achou = falso) {escrever (num); cont := cont + 1;}1;}

33) EQ, (VAR, achou), (LOGIC, 0), (VAR, ##11)33) EQ, (VAR, achou), (LOGIC, 0), (VAR, ##11)

34) JF, (VAR, ##11), (IDLE), (ROTULO, 39)34) JF, (VAR, ##11), (IDLE), (ROTULO, 39)

35) PARAM, (VAR, num), (IDLE), (IDLE)35) PARAM, (VAR, num), (IDLE), (IDLE)

36) WRITE, 1, (IDLE), (IDLE) 36) WRITE, 1, (IDLE), (IDLE)

37) MAIS, (VAR, cont), (INT, 1), (VAR, ##12)37) MAIS, (VAR, cont), (INT, 1), (VAR, ##12)

38) ATRIB, (VAR, ##12), (IDLE), (VAR, cont)38) ATRIB, (VAR, ##12), (IDLE), (VAR, cont)

39) NOP, (IDLE), (IDLE), (IDLE)39) NOP, (IDLE), (IDLE), (IDLE)

Cada linha do código intermediário chama-se quádrupla

Page 10: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Estrutura de dados para o código intermediário de linguagens contendo subprogramas:

Page 11: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Cada lista de quádruplas fica acoplada a um mod-head

As quádruplas do módulo prog destinam-se a:

alocar as variáveis do programa principal (globais)

executar o programa principal

e encerrar tudo no final

Page 12: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

A lista de mod-heads tem um nó-líder e cada lista de quádruplas também tem

Page 13: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Estrutura de dados para código intermediário de linguagens sem subprogramas:

A primeira quádrupla é uma quádrupla-líder, sem conteúdo

Esta estrutura será usada nas próximas aulas

No projeto será usada a do slide anterior

Page 14: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Programa 4.1:Programa 4.1:

O arquivo O arquivo inter012013.y inter012013.y tem um analisador tem um analisador semântico quase acabado para a linguagem semântico quase acabado para a linguagem Sub-Sub-Set2 2013Set2 2013

O arquivo O arquivo inter012013.linter012013.l é seu analisador léxico é seu analisador léxico

O arquivo O arquivo inter012013.y inter012013.y contém ainda contém ainda declarações e funções para auxiliar a construção declarações e funções para auxiliar a construção do código intermediáriodo código intermediário

Rodar esses arquivos com Rodar esses arquivos com inter012013.datinter012013.dat

A seguir, uma descrição dessas A seguir, uma descrição dessas declaraçõesdeclarações e e funçõesfunções

Page 15: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Estrutura de uma quádrupla:Estrutura de uma quádrupla:

typedef struct celquad celquad; typedef struct celquad celquad;

typedef celquad *quadrupla; typedef celquad *quadrupla;

struct celquad {struct celquad {

int num, oper; operando opnd1, opnd2, int num, oper; operando opnd1, opnd2, result;result;

quadrupla prox;quadrupla prox;

};};

O campo O campo num num numera as quádruplasnumera as quádruplas

Não é necessário na compilaçãoNão é necessário na compilação Foi colocado por razões didáticas Foi colocado por razões didáticas

Um Um operandooperando tem dois campos: o tem dois campos: o tipotipo e o e o atributoatributo

oper opnd1

opnd2

result

prox

nu

m

celquad

Page 16: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Estrutura de um operando:Estrutura de um operando:

typedef struct operando operando; typedef struct operando operando;

struct operando {struct operando {

int tipo; atribopnd atr;int tipo; atribopnd atr;

};};

Os tipos dos operandos são:Os tipos dos operandos são:

Operando vazio (idle) Operando vazio (idle) Nome de variávelNome de variável Constantes inteira, real, lógica e caractereConstantes inteira, real, lógica e caractere Cadeia de caracteresCadeia de caracteres Rótulo de quádruplas (ponteiro para Rótulo de quádruplas (ponteiro para

quádruplas)quádruplas) Nome de móduloNome de módulo

tipo

atr

(simb, valint, valfloat, valchar, vallogic, valcad, rotulo, modulo)

operando

Page 17: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Estrutura do atributo de um operando:Estrutura do atributo de um operando:

typedef union atribopnd atribopnd; typedef union atribopnd atribopnd;

union atribopnd {union atribopnd {

simbolo simb; int valint; float valfloat;simbolo simb; int valint; float valfloat;

char valchar; char vallogic; char *valcad;char valchar; char vallogic; char *valcad;

quadrupla rotulo; modhead modulo;quadrupla rotulo; modhead modulo;

};};

Tabela dos atributos conforme o tipo de Tabela dos atributos conforme o tipo de operando:operando:Tipo Atributo Tipo Atributo

Idle - Constante caractere valchar

Nome de variável simb Cadeia de caracteres

valcad

Constante inteira valint Rótulo de quádrupla rotulo

Constante real valfloat Nome de módulo modulo

Constante lógica vallogic

tipo

atr

(simb, valint, valfloat, valchar, vallogic, valcad, rotulo, modulo)

operando

Page 18: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Estrutura de um cabeçalho de módulo:Estrutura de um cabeçalho de módulo:

typedef struct celmodhead celmodhead;typedef struct celmodhead celmodhead;

typedef celmodhead *modhead; typedef celmodhead *modhead;

struct celmodhead {struct celmodhead {

simbolo modname; modhead prox;simbolo modname; modhead prox;

int modtip;int modtip;

quadrupla listquad;quadrupla listquad;

};};

modname

modtip

celmodhead

prox

listquad

Page 19: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Variáveis globais:Variáveis globais:

quadrupla quadcorrente, quadaux;quadrupla quadcorrente, quadaux;modhead codintermed, modcorrente;modhead codintermed, modcorrente;int oper, numquadcorrente;int oper, numquadcorrente;operando opnd1, opnd2, result, opndaux;operando opnd1, opnd2, result, opndaux;int numtemp;int numtemp;const operando opndidle = {IDLEOPND, 0};const operando opndidle = {IDLEOPND, 0};

quadcorrente: quadcorrente: ponteiro para a ponteiro para a celquadcelquad recém-alocada recém-alocada

codintermed: codintermed: ponteiro que dá acesso a todo o código ponteiro que dá acesso a todo o código intermediáriointermediário

modcorrente: modcorrente: ponteiro para a última ponteiro para a última celmodheadcelmodhead alocadaalocada

numtemp:numtemp: usada para controlar a concessão de nomes a usada para controlar a concessão de nomes a variáveis temporáriasvariáveis temporárias

opndidle:opndidle: constante do tipo operando para preencher constante do tipo operando para preencher operandos vazios nas quádruplasoperandos vazios nas quádruplas

Page 20: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Novas definições para os tipos dos Novas definições para os tipos dos identificadores:identificadores:

Relembrando as definições para os tipos Relembrando as definições para os tipos de variáveis:de variáveis:

#define IDPROG 1#define IDVAR 2#define IDFUNC 3#define IDPROC 4

#define NOTVAR 0#define INTEGER 1#define LOGIC 2#define FLOAT 3#define CHAR

4

Page 21: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Definições de constantes para operadores Definições de constantes para operadores de quádruplas:de quádruplas:

#define OPOR1

#define OPAND 2#define OPLT

3#define OPLE 4#define OPGT

5#define OPGE

6#define OPEQ

7#define OPNE

8#define OPMAIS 9#define OPMENOS10

#define OPMULTIP11

#define OPDIV 12#define OPRESTO 13#define OPMENUN

14#define OPNOT 15#define OPATRIB 16#define OPENMOD

17#define NOP 18#define OPJUMP 19#define OPJF 20

Page 22: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Definições de constantes para os tipos dos Definições de constantes para os tipos dos operandos:operandos:

#define IDLEOPND0

#define VAROPND 1#define INTOPND 2#define REALOPND

3#define CHAROPND

4#define LOGICOPND 5#define CADOPND 6#define ROTOPND 7#define MODOPND

8

Page 23: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Protótipos das funções para o código Protótipos das funções para o código intermediário:intermediário:

void InicCodIntermed (void);void InicCodIntermed (void);

void InicCodIntermMod (simbolo);void InicCodIntermMod (simbolo);

quadrupla GeraQuadrupla (int, operando, quadrupla GeraQuadrupla (int, operando, operando, operando, operando);operando);

simbolo NovaTemp (int);simbolo NovaTemp (int);

void ImprimeQuadruplas (void);void ImprimeQuadruplas (void);

void RenumQuadruplas (quadrupla, void RenumQuadruplas (quadrupla, quadrupla);quadrupla);

Page 24: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Função Função InicCodIntermedInicCodIntermed::

void InicCodIntermed () {void InicCodIntermed () {

codintermed = malloc (sizeof (celmodhead));codintermed = malloc (sizeof (celmodhead));

modcorrente = codintermed;modcorrente = codintermed;

modcorrente->listquad = NULL;modcorrente->listquad = NULL;

modcorrente->prox = NULL;modcorrente->prox = NULL;

}}

codintermed

modname

modtip

prox

listquad

modcorrente

Page 25: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Função Função InicCodIntermMod (simbolo simb)InicCodIntermMod (simbolo simb)::

void InicCodIntermMod (simbolo simb) {void InicCodIntermMod (simbolo simb) {modcorrente->prox = malloc (sizeof modcorrente->prox = malloc (sizeof (celmodhead));(celmodhead));modcorrente = modcorrente->prox;modcorrente = modcorrente->prox;modcorrente->prox = NULL;modcorrente->prox = NULL;modcorrente->modname = simb;modcorrente->modname = simb;modcorrente->modtip = simb->tid;modcorrente->modtip = simb->tid;modcorrente->listquad = malloc (sizeof modcorrente->listquad = malloc (sizeof (celquad));(celquad));quadcorrente = modcorrente->listquad;quadcorrente = modcorrente->listquad;quadcorrente->prox = NULL;quadcorrente->prox = NULL;numquadcorrente = 0;numquadcorrente = 0;quadcorrente->num = numquadcorrente;quadcorrente->num = numquadcorrente;

}}

codintermed

simb

num

oper ####

opnd1 ####

opnd2 ####

result ####

prox quadcorrente

0

modname

modtip

prox

listquad

modname

modtip

prox

listquad

modcorrente

● ●

cadeia tid

Page 26: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Função Função GeraQuadrupla (oper, opnd1, GeraQuadrupla (oper, opnd1, opnd2, result)opnd2, result)::

quadrupla GeraQuadrupla (int oper, operando quadrupla GeraQuadrupla (int oper, operando opnd1, operando opnd2, operando result) {opnd1, operando opnd2, operando result) {

quadcorrente->prox = malloc (sizeof (celquad));quadcorrente->prox = malloc (sizeof (celquad));

quadcorrente = quadcorrente->prox;quadcorrente = quadcorrente->prox;

quadcorrente->oper = oper;quadcorrente->oper = oper;

quadcorrente->opnd1 = opnd1;quadcorrente->opnd1 = opnd1;

quadcorrente->opnd2 = opnd2;quadcorrente->opnd2 = opnd2;

quadcorrente->result = result;quadcorrente->result = result;

quadcorrente->prox = NULL;quadcorrente->prox = NULL;

numquadcorrente ++;numquadcorrente ++;

quadcorrente->num = numquadcorrente;quadcorrente->num = numquadcorrente;

return quadcorrente;return quadcorrente;

}}

num 452

oper X

opnd1 YYYY

opnd2 ZZZZ

result WWWW

prox

quadcorrente

453

Roper SSSSopnd1

TTTTopnd2

VVVVresult

TTTT

SSSS

VVVV

R

num

oper

opnd1

opnd2

result

prox valor

retornado

Page 27: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Função Função Novatemp (tip)Novatemp (tip)::

simbolo NovaTemp (int tip) {simbolo NovaTemp (int tip) {

simbolo simb; int temp, i, j;simbolo simb; int temp, i, j;

char nometemp[10] = "##", s[10] = {0};char nometemp[10] = "##", s[10] = {0};

numtemp ++; temp = numtemp;numtemp ++; temp = numtemp;

for (i = 0; temp > 0; temp /= 10, i++)for (i = 0; temp > 0; temp /= 10, i++)

s[i] = temp % 10 + '0';s[i] = temp % 10 + '0';

i --;i --;

for (j = 0; j <= i; j++)for (j = 0; j <= i; j++)

nometemp[2+i-j] = s[j];nometemp[2+i-j] = s[j];

simb = InsereSimb (nometemp, IDVAR, tip);simb = InsereSimb (nometemp, IDVAR, tip);

simb->inic = simb->ref = TRUE;simb->inic = simb->ref = TRUE;

simb->array = FALSE;simb->array = FALSE; return simb;return simb;

}}

Gera um nome para uma nova variável temporária

O nome começa com ## e termina com um número

O número é a soma do último utilizado +1

O nome é inserido na TabSimb e marcado como inicializado e referenciado

Retorna um ponteiro para a célula inserida na TabSimbO tipo da nova variável vem como argumento

Page 28: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Os Os operandosoperandos para as para as quádruplasquádruplas que calculam que calculam o valor de o valor de expressõesexpressões devem estar nos devem estar nos atributosatributos dos não-terminais para a montagem de dos não-terminais para a montagem de expressõesexpressões

Exemplo: Exemplo: seja a produçãoseja a produção

Termo : Termo OPMULT FatorTermo : Termo OPMULT Fator

Deve ser gerada a quádrupla com:Deve ser gerada a quádrupla com:

operador operador correspondente ao atributo de correspondente ao atributo de OPMULTOPMULT

primeiro operando: primeiro operando: no atributo de no atributo de Termo Termo do lado do lado direitodireito

segundo operando:segundo operando: no atributo de no atributo de FatorFator

operando resultado:operando resultado: no atributo de no atributo de Termo Termo do lado do lado esquerdoesquerdo

Page 29: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Não-terminais para a montagem de expressões:Não-terminais para a montagem de expressões:

Expressao, ExprAux1, ExprAux2, ExprAux3, Expressao, ExprAux1, ExprAux2, ExprAux3, ExprAux4,ExprAux4,

Termo, FatorTermo, Fator

Esses não-terminais já guardam seus Esses não-terminais já guardam seus tipostipos em em seus atributos, para os testes de seus atributos, para os testes de compatibilidadecompatibilidade entre operadores e operandos:entre operadores e operandos:

%type <tipoexpr>%type <tipoexpr> Expressao ExprAux1 Expressao ExprAux1 ExprAux2 ExprAux2 ExprAux3 ExprAux3 ExprAux4 Termo FatorExprAux4 Termo Fator

Agora, o atributo desses não-terminais deverá ter Agora, o atributo desses não-terminais deverá ter dois campos:dois campos:

o o tipotipo e o e o operandooperando

Page 30: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Seja também a produção:Seja também a produção:

Fator : VariavelFator : Variavel

É conveniente também que o não-terminal É conveniente também que o não-terminal Variavel Variavel carregue um carregue um operandooperando em seu atributo, em seu atributo, para que o operando de para que o operando de FatorFator receba esse receba esse operandooperando

Esse não-terminal já guarda em seu atributo um Esse não-terminal já guarda em seu atributo um ponteiroponteiro para a para a TabSimbTabSimb, para os testes de , para os testes de compatibilidadecompatibilidade entre operadores e operandos: entre operadores e operandos:

%type <simb> Variavel%type <simb> Variavel

Agora, o atributo desse não-terminal deverá ter Agora, o atributo desse não-terminal deverá ter dois campos:dois campos:

o referido ponteiro e o o referido ponteiro e o operandooperando

Page 31: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Novas declarações para atributos de expressões e Novas declarações para atributos de expressões e variáveis:variáveis:

typedef struct infoexpressao infoexpressao;typedef struct infoexpressao infoexpressao;

struct infoexpressao { int tipo; operando opnd; };struct infoexpressao { int tipo; operando opnd; };

typedef struct infovariavel infovariavel;typedef struct infovariavel infovariavel;

struct infovariavel { simbolo simb; operando opnd; };struct infovariavel { simbolo simb; operando opnd; };

Novos campos para a declaração Novos campos para a declaração %union%union::

%union {%union {

char cadeia[50]; int atr, valint; float valreal; char char cadeia[50]; int atr, valint; float valreal; char carac;carac;

infoexpressao infoexpr;infoexpressao infoexpr; infovariavel infovar; infovariavel infovar;

simbolo simb; int dim; int nsubscr;simbolo simb; int dim; int nsubscr;

}}

Page 32: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Novos campos para a declaração Novos campos para a declaração %union%union::

%union {%union {

char cadeia[50]; int atr, valint; float valreal; char cadeia[50]; int atr, valint; float valreal; char carac;char carac;

infoexpressao infoexpr;infoexpressao infoexpr; infovariavel infovariavel infovar;infovar;

simbolo simb; int dim; int nsubscr;simbolo simb; int dim; int nsubscr;

}}

Novas especificações para os atributos dos Novas especificações para os atributos dos não-terminais envolvidos:não-terminais envolvidos:

%type <%type <infovarinfovar> Variavel> Variavel

%type <%type <infoexprinfoexpr> > Expressao ExprAux1 Expressao ExprAux1 ExprAux2 ExprAux2 ExprAux3 ExprAux3 ExprAux4 Termo FatorExprAux4 Termo Fator

Antes era <simb>

Antes era <tipoexpr>

Page 33: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Nas produções onde aparecem não-terminais Nas produções onde aparecem não-terminais envolvidos no cálculo de expressões foi trocado envolvidos no cálculo de expressões foi trocado $$$$ por por $$.tipo$$.tipo e e $1$1, , $2$2, etc. por , etc. por $1.tipo$1.tipo, , $2.tipo$2.tipo, etc., etc.

Nas ocorrências de atributos do não terminal Nas ocorrências de atributos do não terminal VariavelVariavel, foi trocado , foi trocado $$$$ por por $$.simb$$.simb e e $1$1, , $2$2, , etc. por etc. por $1.simb$1.simb, , $2.simb$2.simb, etc., etc.

Page 34: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Exercício 4.1: Exercício 4.1: Inicializar o código intermediário e a Inicializar o código intermediário e a lista de quádruplas do único módulo,lista de quádruplas do único módulo, imprimindo-imprimindo-as (a lista é vazia)as (a lista é vazia)

Na produção do não-terminal Na produção do não-terminal ProgProg::

ProgProg :: {{

InicTabSimb (); InicTabSimb (); InicCodIntermed (); numtemp = InicCodIntermed (); numtemp = 0;0;

} PROGRAMA ID PVIRG { printf ("programa %s ;\n", } PROGRAMA ID PVIRG { printf ("programa %s ;\n", $3);$3);

simb =simb = InsereSimb ($3, IDPROG, NOTVAR); InsereSimb ($3, IDPROG, NOTVAR);

InicCodIntermMod (simb);InicCodIntermMod (simb);

} Decls CmdComp { } Decls CmdComp {

VerificaInicRef (); ImprimeTabSimb ();VerificaInicRef (); ImprimeTabSimb ();

ImprimeQuadruplas ();ImprimeQuadruplas ();

}}

;;

Acrescentar ao arquivo inter012013.y o código em destaque Rodar com o arquivo inter012013.dat

Page 35: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Exercício 4.2: Exercício 4.2: Inserir a quádrupla Inserir a quádrupla OPENMODOPENMOD

Ainda na produção do não-terminal Ainda na produção do não-terminal ProgProg::

Prog:Prog: {- - - - -} PROGRAMA ID PVIRG {{- - - - -} PROGRAMA ID PVIRG {

- - - - -- - - - -

InicCodIntermMod (simb);InicCodIntermMod (simb);

opnd1.tipo = MODOPND;opnd1.tipo = MODOPND;

opnd1.atr.modulo = modcorrente;opnd1.atr.modulo = modcorrente;

GeraQuadrupla (OPENMOD, opnd1, GeraQuadrupla (OPENMOD, opnd1, opndidle, opndidle);opndidle, opndidle);

} Decls CmdComp {} Decls CmdComp {

- - - - -- - - - -

}}

;;

Acrescentar ao arquivo inter012013. y o código em destaqueRodar com o arquivo inter012013. dat

Page 36: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Exercício 4.3: Exercício 4.3: Inserir quádruplas para Inserir quádruplas para expressões sem variáveis indexadasexpressões sem variáveis indexadas

Exemplo:Exemplo: as quádruplas para a expressão: as quádruplas para a expressão:

(i+3 >= j-2) && b2(i+3 >= j-2) && b2

sendo: sendo: int i, j; logic b2;int i, j; logic b2;

podem ser: podem ser:

MAIS, (VAR, i), (INT, 3), (VAR, ##1)MAIS, (VAR, i), (INT, 3), (VAR, ##1)

MENOS, (VAR, j), (INT, 2), (VAR, ##2)MENOS, (VAR, j), (INT, 2), (VAR, ##2)

GE, (VAR, ##1), (VAR, ##2), (VAR, ##3)GE, (VAR, ##1), (VAR, ##2), (VAR, ##3)

AND, (VAR, ##3), (VAR, b2), (VAR, ##4)AND, (VAR, ##3), (VAR, b2), (VAR, ##4)

Page 37: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

É necessária uma É necessária uma programaçãoprogramação em todos os em todos os não-terminais envolvendo não-terminais envolvendo expressõesexpressões

Em toda produção que contribui para a Em toda produção que contribui para a formação de expressõesformação de expressões, deve-se calcular o , deve-se calcular o atributo operandoatributo operando do não-terminal do do não-terminal do lado lado esquerdoesquerdo

Numa produção onde aparece Numa produção onde aparece operadoroperador de de expressões, além desse cálculo, deve-se expressões, além desse cálculo, deve-se gerar gerar quádruplaquádrupla com a com a operaçãooperação correspondente e correspondente e com os com os atributos operandosatributos operandos dos não- dos não-terminais de expressõesterminais de expressões

  

Page 38: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Na 1ª produção do não-terminal Na 1ª produção do não-terminal Variavel Variavel (sem (sem subscritos), calcula-se seu subscritos), calcula-se seu operandooperando::

Variavel: ID {- - - - -Variavel: ID {- - - - -

$$.simb = simb;$$.simb = simb;

if ($$.simb != NULL) if ($$.simb != NULL) {{

if (- - - - -) Esperado ("Subscrito\(s)");if (- - - - -) Esperado ("Subscrito\(s)");

$$.opnd.tipo = VAROPND;$$.opnd.tipo = VAROPND;

$$.opnd.atr.simb = $$.simb;$$.opnd.atr.simb = $$.simb;

}}

}}

;;

Page 39: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Nas produções sem operadores do não-Nas produções sem operadores do não-terminal terminal FatorFator, calcula-se seu , calcula-se seu operandooperando::

FatorFator : Variavel {: Variavel {

if ($1.simb != NULL) {if ($1.simb != NULL) {

- - - - - $$.tipo = $1.simb->tvar; - - - - - $$.tipo = $1.simb->tvar; $$.opnd $$.opnd = $1.opnd; = $1.opnd; }}

}}

| CTINT { - - - - - $$.tipo = INTEGER;| CTINT { - - - - - $$.tipo = INTEGER;

$$.opnd.tipo = INTOPND;$$.opnd.tipo = INTOPND;

$$.opnd.atr.valint = $1;$$.opnd.atr.valint = $1;

}}

| CTREAL { - - - - - $$.tipo = FLOAT;| CTREAL { - - - - - $$.tipo = FLOAT;

$$.opnd.tipo = REALOPND;$$.opnd.tipo = REALOPND;

$$.opnd.atr.valfloat = $1;$$.opnd.atr.valfloat = $1;

}}

Page 40: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Fator: CTCARAC { - - - - - $$.tipo = CHAR;Fator: CTCARAC { - - - - - $$.tipo = CHAR;

$$.opnd.tipo = CHAROPND;$$.opnd.tipo = CHAROPND;

$$.opnd.atr.valchar = $1;$$.opnd.atr.valchar = $1;

}}

| VERDADE { - - - - - $$.tipo = LOGICAL;| VERDADE { - - - - - $$.tipo = LOGICAL;

$$.opnd.tipo = LOGICOPND;$$.opnd.tipo = LOGICOPND;

$$.opnd.atr.vallogic = 1;$$.opnd.atr.vallogic = 1;

}}

| FALSO { - - - - - $$.tipo = LOGICAL;| FALSO { - - - - - $$.tipo = LOGICAL;

$$.opnd.tipo = LOGICOPND;$$.opnd.tipo = LOGICOPND;

$$.opnd.atr.vallogic = 0;$$.opnd.atr.vallogic = 0;

}}

| ABPAR {- - - - -} Expressao FPAR {| ABPAR {- - - - -} Expressao FPAR {

- - - - - $$.tipo = $3.tipo; - - - - - $$.tipo = $3.tipo; $$.opnd = $3.opnd;$$.opnd = $3.opnd;

}}

Page 41: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Na produção do não-terminal Na produção do não-terminal FatorFator, com o , com o operador operador NEGNEG gera-se uma quádrupla, além de gera-se uma quádrupla, além de calcular o operando do lado esquerdo:calcular o operando do lado esquerdo:

FatorFator : NEG {- - - - -} Fator {: NEG {- - - - -} Fator {

if ( - - - - - ) Incompatibilidade ( - - - - - );if ( - - - - - ) Incompatibilidade ( - - - - - );

if ($3.tipo == FLOAT) $$.tipo = FLOAT;if ($3.tipo == FLOAT) $$.tipo = FLOAT;

else $$.tipo = INTEGER;else $$.tipo = INTEGER;

$$.opnd.tipo = VAROPND;$$.opnd.tipo = VAROPND;

$$.opnd.atr.simb = NovaTemp ($$.tipo);$$.opnd.atr.simb = NovaTemp ($$.tipo);

GeraQuadrupla (OPMENUN, $3.opnd, GeraQuadrupla (OPMENUN, $3.opnd, opndidle, $$.opnd);opndidle, $$.opnd);

} }

;;Rodar com o arquivo inter012013. dat

Page 42: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Produções do não-terminal Produções do não-terminal TermoTermo::

Termo : Fator Termo : Fator /* default: $$ = $1 *//* default: $$ = $1 */|| Termo OPMULT {- - - - -} Fator {Termo OPMULT {- - - - -} Fator {

switch ($2) {switch ($2) {case MULT: case DIV: - - - - -case MULT: case DIV: - - - - -

$$.opnd.tipo = VAROPND; $$.opnd.tipo = VAROPND; $$.opnd.atr.simb = NovaTemp ($$.tipo);$$.opnd.atr.simb = NovaTemp ($$.tipo);if ($2 == MULT) if ($2 == MULT) GeraQuadrupla (OPMULTIP, $1.opnd, $4.opnd, GeraQuadrupla (OPMULTIP, $1.opnd, $4.opnd,

$$.opnd);$$.opnd);else GeraQuadrupla (OPDIV, $1.opnd, $4.opnd, $else GeraQuadrupla (OPDIV, $1.opnd, $4.opnd, $

$.opnd);$.opnd); break;break;

case RESTO: - - - - -case RESTO: - - - - -$$.opnd.tipo = VAROPND; $$.opnd.tipo = VAROPND; $$.opnd.atr.simb = NovaTemp ($$.tipo);$$.opnd.atr.simb = NovaTemp ($$.tipo);GeraQuadrupla (OPRESTO, $1.opnd, $4.opnd, $GeraQuadrupla (OPRESTO, $1.opnd, $4.opnd, $

$.opnd);$.opnd);break;break;

}}}};;

Rodar com o arquivo inter012013. dat

Fazer programação análoga para as produções dos não terminais ExprAux4, ExprAux3, ExprAux2, ExprAux1 e Expressao

Page 43: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Exercício 4.4: Exercício 4.4: Inserir quádruplas para comandos Inserir quádruplas para comandos de atribuiçãode atribuição

Exemplo:Exemplo: as quádruplas para a atribuição: as quádruplas para a atribuição:

b1 := (i+3 >= j-2) && b2b1 := (i+3 >= j-2) && b2

sendo: sendo: int i, j; logic b1, b2;int i, j; logic b1, b2;

podem ser: podem ser:

MAIS, (VAR, i), (INT, 3), (VAR, ##1)MAIS, (VAR, i), (INT, 3), (VAR, ##1)

MENOS, (VAR, j), (INT, 2), (VAR, ##2)MENOS, (VAR, j), (INT, 2), (VAR, ##2)

GE, (VAR, ##1), (VAR, ##2), (VAR, ##3)GE, (VAR, ##1), (VAR, ##2), (VAR, ##3)

AND, (VAR, ##3), (VAR, b2), (VAR, ##4)AND, (VAR, ##3), (VAR, b2), (VAR, ##4)

ATRIB, (VAR, ##4), (IDLE), (VAR, b1)ATRIB, (VAR, ##4), (IDLE), (VAR, b1)

  

Page 44: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Exercício 4.5: Exercício 4.5: Inserir quádruplas para comandos Inserir quádruplas para comandos condicionaiscondicionais

Primeiramente, sejam os comandos Primeiramente, sejam os comandos se sem senaose sem senao

Exemplo:Exemplo: as quádruplas para o comando as quádruplas para o comando

se (i < j) { i = i+3; n := v/h; }se (i < j) { i = i+3; n := v/h; }

podem ser:podem ser:

2) LT, (VAR, i), (VAR, j), (VAR, ##1)2) LT, (VAR, i), (VAR, j), (VAR, ##1)

3) JF, (VAR, ##1), (IDLE), (ROTULO, 8)3) JF, (VAR, ##1), (IDLE), (ROTULO, 8)

4) MAIS, (VAR, i), (INT, 3), (VAR, ##2)4) MAIS, (VAR, i), (INT, 3), (VAR, ##2)

5) ATRIB, (VAR, ##2), (IDLE), (VAR, i)5) ATRIB, (VAR, ##2), (IDLE), (VAR, i)

6) DIV, (VAR, v), (VAR, h), (VAR, ##3)6) DIV, (VAR, v), (VAR, h), (VAR, ##3)

7) ATRIB, (VAR, ##3), (IDLE), (VAR, n)7) ATRIB, (VAR, ##3), (IDLE), (VAR, n)

8) NOP, (IDLE), (IDLE), (IDLE)8) NOP, (IDLE), (IDLE), (IDLE)

  

Usar os arquivos inter022013.y, inter022013.l e inter022013.dat

Page 45: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Arquivo inter022013.y:Arquivo inter022013.y:

Gera quádruplas para abrir módulo, operadores de Gera quádruplas para abrir módulo, operadores de expressões e comandos de atribuiçãoexpressões e comandos de atribuição

Função RenumQuadruplas (q1, q2): Função RenumQuadruplas (q1, q2):

Algumas quádruplas serão geradas Algumas quádruplas serão geradas fora de fora de ordemordem

Sua Sua ordemordem deve ser deve ser corrigidacorrigida Para fins Para fins didáticosdidáticos, as quádruplas serão , as quádruplas serão

renumeradasrenumeradas

Abrir o arquivo Abrir o arquivo inter022013.datinter022013.dat Rodar Rodar flexflex, , yaccyacc, , gccgcc e executável gerado e executável gerado A cada implementação, alterar os comentários em A cada implementação, alterar os comentários em

inter022013.datinter022013.dat

Page 46: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

A programação para A programação para se sem senaose sem senao está na está na produção do não-terminal produção do não-terminal CmdSeCmdSe::

CmdSeCmdSe : SE ABPAR {- - - - -} Expressao {: SE ABPAR {- - - - -} Expressao {

- - - - -- - - - -

opndaux.tipo = ROTOPND;opndaux.tipo = ROTOPND;

$<quad>$ = $<quad>$ =

GeraQuadrupla (OPJF, $4.opnd, GeraQuadrupla (OPJF, $4.opnd, opndidle, opndaux);opndidle, opndaux);

} FPAR {printf (") ");} Comando } FPAR {printf (") ");} Comando {{

$<quad>5->result.atr.rotulo =$<quad>5->result.atr.rotulo =

GeraQuadrupla (NOP, opndidle, GeraQuadrupla (NOP, opndidle, opndidle, opndidle);opndidle, opndidle);

}} CmdSenao CmdSenao

;;É necessário acrescentar o campo quad na declaração %union: quadrupla quad;

Page 47: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

A programação para A programação para se sem senaose sem senao está na está na produção do não-terminal produção do não-terminal CmdSeCmdSe::

CmdSeCmdSe : SE ABPAR {- - - - -} Expressao {: SE ABPAR {- - - - -} Expressao {

- - - - -- - - - -

opndaux.tipo = ROTOPND;opndaux.tipo = ROTOPND;

$<quad>$ = $<quad>$ =

GeraQuadrupla (OPJF, $4.opnd, GeraQuadrupla (OPJF, $4.opnd, opndidle, opndaux);opndidle, opndaux);

} FPAR {printf (") ");} Comando } FPAR {printf (") ");} Comando {{

$<quad>5->result.atr.rotulo =$<quad>5->result.atr.rotulo =

GeraQuadrupla (NOP, opndidle, GeraQuadrupla (NOP, opndidle, opndidle, opndidle);opndidle, opndidle);

}} CmdSenao CmdSenao

;;No arquivo inter022013.dat, tirar o comentário do se sem senao e rodar

Page 48: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

CmdSeCmdSe : SE ABPAR {- - - - -} Expressao {: SE ABPAR {- - - - -} Expressao {

- - - - -- - - - -

opndaux.tipo = ROTOPND;opndaux.tipo = ROTOPND;

$<quad>$ = GeraQuadrupla (OPJF, $4.opnd, opndidle, $<quad>$ = GeraQuadrupla (OPJF, $4.opnd, opndidle, opndaux);opndaux);

} FPAR {printf (") ");} Comando } FPAR {printf (") ");} Comando {{

$<quad>5->result.atr.rotulo =$<quad>5->result.atr.rotulo =

GeraQuadrupla (NOP, opndidle, opndidle, opndidle);GeraQuadrupla (NOP, opndidle, opndidle, opndidle);

}} CmdSenao CmdSenao

;;

Expressao

----- ----- ----- ##n

JF ##n ----- ROT

$5

Comando

NOP ----- ----- -----

A quádrupla destino do desvio é gerada na produção de CmdSe

NOP é eliminada na otimização do código intermediário

?

Page 49: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Sejam agora os comandos Sejam agora os comandos se com senaose com senao

Exemplo:Exemplo: as quádruplas para os comandos as quádruplas para os comandos

se (i < j) { i := i+3; n := v/h; }se (i < j) { i := i+3; n := v/h; }

senao { v := h; i := j; }senao { v := h; i := j; }

n := v;n := v;

podem ser:podem ser:

  

2) LT, (VAR, i), (VAR, j), (VAR, ##1)3) JF, (VAR, ##1), (IDLE), (ROTULO, 9)4) MAIS, (VAR, i), (INT, 3), (VAR, ##2)5) ATRIB, (VAR, ##2), (IDLE), (VAR, i)6) DIV, (VAR, v), (VAR, h), (VAR, ##3)7) ATRIB, (VAR, ##3), (IDLE), (VAR, n)8) JUMP, (IDLE), (IDLE), (ROTULO, 12)9) NOP, (IDLE), (IDLE), (IDLE)10) ATRIB, (VAR, h), (IDLE), (VAR, v)11) ATRIB, (VAR, j), (IDLE), (VAR, i)12) NOP, (IDLE), (IDLE), (IDLE)13) ATRIB, (VAR, v), (IDLE), (VAR, n)

Page 50: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

A programação para A programação para se com senaose com senao está nas está nas produções dos não-terminais produções dos não-terminais CmdSeCmdSe e e CmdSenaoCmdSenao::

CmdSeCmdSe : SE ABPAR {- - - - -} Expressao { - - - - -: SE ABPAR {- - - - -} Expressao { - - - - - opndaux.tipo = ROTOPND;opndaux.tipo = ROTOPND;

$<quad>$ = GeraQuadrupla (OPJF, $4.opnd, opndidle, $<quad>$ = GeraQuadrupla (OPJF, $4.opnd, opndidle, opndaux);opndaux);} FPAR {printf (") ");} Comando {} FPAR {printf (") ");} Comando {

$<quad>$ = quadcorrente;$<quad>$ = quadcorrente;$<quad>5->result.atr.rotulo =$<quad>5->result.atr.rotulo =

GeraQuadrupla (NOP, opndidle, opndidle, opndidle);GeraQuadrupla (NOP, opndidle, opndidle, opndidle);} CmdSenao } CmdSenao {{

if ($<quad>9->prox != quadcorrente) {if ($<quad>9->prox != quadcorrente) {quadaux = $<quad>9->prox;quadaux = $<quad>9->prox;$<quad>9->prox = quadaux->prox;$<quad>9->prox = quadaux->prox;quadaux->prox = $<quad>9->prox->prox;quadaux->prox = $<quad>9->prox->prox;$<quad>9->prox->prox = quadaux;$<quad>9->prox->prox = quadaux;RenumQuadruplas ($<quad>9, quadcorrente);RenumQuadruplas ($<quad>9, quadcorrente);

}}}}

;;

Page 51: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

CmdSenaoCmdSenao ::

| SENAO {| SENAO {

- - - - -- - - - -

opndaux.tipo = ROTOPND;opndaux.tipo = ROTOPND;

$<quad>$ = GeraQuadrupla (OPJUMP, $<quad>$ = GeraQuadrupla (OPJUMP, opndidle, opndidle, opndidle, opndidle, opndaux);opndaux);

} Comando } Comando {{

$<quad>2->result.atr.rotulo =$<quad>2->result.atr.rotulo =

GeraQuadrupla (NOP, opndidle, GeraQuadrupla (NOP, opndidle, opndidle, opndidle);opndidle, opndidle);

}}

;;

No arquivo inter022013.dat, tirar o comentário do se com senao e rodar

Page 52: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

CmdSeCmdSe : SE ABPAR {- - - - -} Expressao { - - - - -: SE ABPAR {- - - - -} Expressao { - - - - -opndaux.tipo = ROTOPND;opndaux.tipo = ROTOPND;$<quad>$ = GeraQuadrupla (OPJF, $4.opnd, opndidle, $<quad>$ = GeraQuadrupla (OPJF, $4.opnd, opndidle,

opndaux);opndaux);} FPAR {- - - - -} Comando {} FPAR {- - - - -} Comando {

$<quad>$ = quadcorrente;$<quad>$ = quadcorrente;$<quad>5->result.atr.rotulo =$<quad>5->result.atr.rotulo =

GeraQuadrupla (NOP, opndidle, opndidle, GeraQuadrupla (NOP, opndidle, opndidle, opndidle);opndidle);} CmdSenao } CmdSenao {- - - - -}{- - - - -}

;; Expressao

----- ----- ----- ##n

JF ##n ----- ROT

Comando

NOP ----- ----- -----

$5

$9

Page 53: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

CmdSenaoCmdSenao :: | SENAO { - - - - -| SENAO { - - - - -

opndaux.tipo = ROTOPND;opndaux.tipo = ROTOPND;

$<quad>$ = GeraQuadrupla (OPJUMP, opndidle, $<quad>$ = GeraQuadrupla (OPJUMP, opndidle, opndidle, opndaux);opndidle, opndaux);

} Comando } Comando {{

$<quad>2->result.atr.rotulo =$<quad>2->result.atr.rotulo =

GeraQuadrupla (NOP, opndidle, opndidle, GeraQuadrupla (NOP, opndidle, opndidle, opndidle);opndidle);

}}

;;

Expressao

----- ----- ----- ##n

JF ##n ----- ROT

Comando

NOP ----- ----- -----

$5

$9

JUMP ----- ----- ROT

$2

As quádruplas NOP e JUMP foram geradas em ordem trocada

?

Page 54: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

CmdSenaoCmdSenao :: | SENAO { - - - - -| SENAO { - - - - -

opndaux.tipo = ROTOPND;opndaux.tipo = ROTOPND;

$<quad>$ = GeraQuadrupla (OPJUMP, opndidle, $<quad>$ = GeraQuadrupla (OPJUMP, opndidle, opndidle, opndaux);opndidle, opndaux);

} Comando } Comando {{

$<quad>2->result.atr.rotulo =$<quad>2->result.atr.rotulo =

GeraQuadrupla (NOP, opndidle, opndidle, GeraQuadrupla (NOP, opndidle, opndidle, opndidle);opndidle);

}}

;;

Expressao

----- ----- ----- ##n

JF ##n ----- ROT

Comando

NOP ----- ----- -----

$5

$9

JUMP ----- ----- ROT

$2

Comando

NOP ----- ----- -----

É preciso inverter a ordem das quádruplas NOP e JUMP

?

Page 55: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

CmdSeCmdSe : SE ABPAR {- - - - -} Expressao {- - - - -} FPAR {- - - - : SE ABPAR {- - - - -} Expressao {- - - - -} FPAR {- - - - -} Comando -} Comando

{ - - - - -} CmdSenao { - - - - -} CmdSenao {{if ($<quad>9->prox != quadcorrente) {if ($<quad>9->prox != quadcorrente) {

quadaux = $<quad>9->prox;quadaux = $<quad>9->prox;$<quad>9->prox = quadaux->prox;$<quad>9->prox = quadaux->prox;quadaux->prox = quadaux->prox =

$<quad>9->prox->prox;$<quad>9->prox->prox;$<quad>9->prox->prox = quadaux;$<quad>9->prox->prox = quadaux;RenumQuadruplas RenumQuadruplas

($<quad>9, quadcorrente);($<quad>9, quadcorrente);

}}}}

;;

Comando

NOP ----- ----- -----

$9

JUMP ----- ----- ROT

Comando

NOP ----- ----- -----

Se a quádrupla seguinte à $9 for a quádrupla corrente, o se não tem senao – não é preciso fazer troca

quadaux

Page 56: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Exercício 4.6: Exercício 4.6: Inserir quádruplas para o Inserir quádruplas para o comando comando enquantoenquanto

Exemplo:Exemplo: as quádruplas para o comando as quádruplas para o comando

enquanto (i < j) i := j + h;enquanto (i < j) i := j + h;

i := 0;i := 0;

podem ser:podem ser:

2) NOP, (IDLE), (IDLE), (IDLE)2) NOP, (IDLE), (IDLE), (IDLE)

3) LT, (VAR, i), (VAR, j), (VAR, ##1)3) LT, (VAR, i), (VAR, j), (VAR, ##1)

4) JF, (VAR, ##1), (IDLE), (ROTULO, 8)4) JF, (VAR, ##1), (IDLE), (ROTULO, 8)

5) MAIS, (VAR, j), (VAR, h), (VAR, ##2)5) MAIS, (VAR, j), (VAR, h), (VAR, ##2)

6) ATRIB, (VAR, ##2), (IDLE), (VAR, i)6) ATRIB, (VAR, ##2), (IDLE), (VAR, i)

7) JUMP, (IDLE), (IDLE), (ROTULO, 2)7) JUMP, (IDLE), (IDLE), (ROTULO, 2)

8) NOP, (IDLE), (IDLE), (IDLE)8) NOP, (IDLE), (IDLE), (IDLE)

9) ATRIB, (INT, 0), (IDLE), (VAR, i)9) ATRIB, (INT, 0), (IDLE), (VAR, i)

Page 57: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

CmdEnquantoCmdEnquanto : ENQUANTO ABPAR Expressao FPAR : ENQUANTO ABPAR Expressao FPAR ComandoComando

;;

Expressao

----- ----- ----- ##n

JF ##n ----- ROT

Comando

NOP ----- ----- -----

NOP ----- ----- -----

JUMP -----

----- ROT

?

Page 58: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Exercício 4.7: Exercício 4.7: Inserir quádruplas para comandos Inserir quádruplas para comandos lerler e e escreverescrever

Exemplo:Exemplo: as quádruplas para os comandos as quádruplas para os comandos

ler (a, b, c);ler (a, b, c);

escrever ("Valor de a+b:", a+b, "Valor de c:", escrever ("Valor de a+b:", a+b, "Valor de c:", c);c);

podem ser:podem ser:

2) PARAM, (VAR, a), (IDLE), (IDLE)2) PARAM, (VAR, a), (IDLE), (IDLE)3) PARAM, (VAR, b), (IDLE), (IDLE)3) PARAM, (VAR, b), (IDLE), (IDLE)4) PARAM, (VAR, c), (IDLE), (IDLE)4) PARAM, (VAR, c), (IDLE), (IDLE)5) READ, (INT, 3), (IDLE), (IDLE)5) READ, (INT, 3), (IDLE), (IDLE)6) PARAM, (CADEIA, Valor de a+b:), (IDLE), (IDLE)6) PARAM, (CADEIA, Valor de a+b:), (IDLE), (IDLE)7) MAIS, (VAR, a), (VAR, b), (VAR, ##1)7) MAIS, (VAR, a), (VAR, b), (VAR, ##1)8) PARAM, (VAR, ##1), (IDLE), (IDLE)8) PARAM, (VAR, ##1), (IDLE), (IDLE)9) PARAM, (CADEIA, Valor de c:), (IDLE), (IDLE)9) PARAM, (CADEIA, Valor de c:), (IDLE), (IDLE)10) PARAM, (VAR, c), (IDLE), (IDLE)10) PARAM, (VAR, c), (IDLE), (IDLE)11) WRITE, (INT, 4), (IDLE), (IDLE)11) WRITE, (INT, 4), (IDLE), (IDLE)

Os operadores de quádruplas PARAM, OPREAD e OPWRITE já estão declarados no programa inter022013.y

Page 59: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

2) PARAM, (VAR, a), (IDLE), (IDLE)2) PARAM, (VAR, a), (IDLE), (IDLE)

3) PARAM, (VAR, b), (IDLE), (IDLE)3) PARAM, (VAR, b), (IDLE), (IDLE)

4) PARAM, (VAR, c), (IDLE), (IDLE)4) PARAM, (VAR, c), (IDLE), (IDLE)

5) READ, (INT, 3), (IDLE), (IDLE)5) READ, (INT, 3), (IDLE), (IDLE)

6) PARAM, (CADEIA, Valor de a+b:), (IDLE), (IDLE)6) PARAM, (CADEIA, Valor de a+b:), (IDLE), (IDLE)

7) MAIS, (VAR, a), (VAR, b), (VAR, ##1)7) MAIS, (VAR, a), (VAR, b), (VAR, ##1)

8) PARAM, (VAR, ##1), (IDLE), (IDLE)8) PARAM, (VAR, ##1), (IDLE), (IDLE)

9) PARAM, (CADEIA, Valor de c:), (IDLE), (IDLE)9) PARAM, (CADEIA, Valor de c:), (IDLE), (IDLE)

10) PARAM, (VAR, c), (IDLE), (IDLE)10) PARAM, (VAR, c), (IDLE), (IDLE)

11) WRITE, (INT, 4), (IDLE), (IDLE)11) WRITE, (INT, 4), (IDLE), (IDLE)

  

Elementos de escrita também podem ser operandos de quádruplas

São úteis contadores de argumentos para os comandos ler e escrever

Isso será feito nas produções dos não-terminais ListVar e ListEscr

Page 60: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

O atributo dos não-terminais O atributo dos não-terminais ListVarListVar e e ListEscrListEscr deve ser o número de argumentos de suas listasdeve ser o número de argumentos de suas listas

Deve-se acrescentar mais um campo na Deve-se acrescentar mais um campo na declaração declaração %union%union::

%union {%union {

- - - - -- - - - -

int nsubscr, int nsubscr, nargsnargs;;

- - - - -- - - - -

}}

Declaração do atributo dos não terminais Declaração do atributo dos não terminais ListVarListVar e e ListEscrListEscr::

%type <nargs>%type <nargs> ListVar ListEscrListVar ListEscr

Page 61: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Tal como uma expressão, o não terminal Tal como uma expressão, o não terminal ElemEscrElemEscr deve ter um operando de quádrupla deve ter um operando de quádrupla

Então deve haver uma declaração Então deve haver uma declaração %type%type para para ele:ele:

%type %type <infoexpr> <infoexpr> Expressao ExprAux1 Expressao ExprAux1 ExprAux2ExprAux2

ExprAux3 ExprAux4 ExprAux3 ExprAux4 Termo Termo Fator Fator ElemEscrElemEscr

  

Page 62: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Programação para o não-terminal Programação para o não-terminal ListVarListVar que é que é usado na produção do não-terminal usado na produção do não-terminal CmdLerCmdLer::

ListVarListVar : Variavel { - - - - -: Variavel { - - - - -

$$ = 1;$$ = 1;

GeraQuadrupla (PARAM, $1.opnd, opndidle, GeraQuadrupla (PARAM, $1.opnd, opndidle, opndidle);opndidle);

}}

| ListVar VIRG { - - - - - } Variavel {| ListVar VIRG { - - - - - } Variavel {

- - - - -- - - - -

$$ = $1 + 1;$$ = $1 + 1;

GeraQuadrupla (PARAM, $4.opnd, opndidle, GeraQuadrupla (PARAM, $4.opnd, opndidle, opndidle);opndidle);

}}

;;

  

$$ é o contador de argumentos de um comando ler

Page 63: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Programação para o não-terminal Programação para o não-terminal CmdLerCmdLer::

CmdLerCmdLer: LER ABPAR { - - - - -} : LER ABPAR { - - - - -}

ListVarListVar

{{

opnd1.tipo = INTOPND;opnd1.tipo = INTOPND;

opnd1.atr.valint = $4;opnd1.atr.valint = $4;

GeraQuadrupla (OPREAD, opnd1, opndidle, GeraQuadrupla (OPREAD, opnd1, opndidle, opndidle);opndidle);

}}

FPAR PVIRG {printf (") ;\n");}FPAR PVIRG {printf (") ;\n");}

;;

Page 64: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Programação para o não-terminal Programação para o não-terminal ElemEscrElemEscr::

ElemEscrElemEscr : CADEIA {: CADEIA {

printf ("%s ", $1);printf ("%s ", $1);

$$.opnd.tipo = CADOPND;$$.opnd.tipo = CADOPND;

$$.opnd.atr.valcad = malloc (strlen($1) + 1);$$.opnd.atr.valcad = malloc (strlen($1) + 1);

strcpy ($$.opnd.atr.valcad, $1);strcpy ($$.opnd.atr.valcad, $1);

}}

| Expressao| Expressao /* default: $$ = $1 *//* default: $$ = $1 */

;;

Obs.: $$.tipo da 1ª produção do não-terminal ElemEscr não é usado

Portanto não é calculado

Page 65: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Programação para o não-terminal Programação para o não-terminal ListEscrListEscr::

ListEscrListEscr : ElemEscr: ElemEscr

{{

$$ = 1;$$ = 1;

GeraQuadrupla (PARAM, $1.opnd, opndidle, GeraQuadrupla (PARAM, $1.opnd, opndidle, opndidle);opndidle);

}}

| ListEscr VIRG {printf (", ");} ElemEscr| ListEscr VIRG {printf (", ");} ElemEscr

{{

$$ = $1 + 1;$$ = $1 + 1;

GeraQuadrupla (PARAM, $4.opnd, opndidle, GeraQuadrupla (PARAM, $4.opnd, opndidle, opndidle);opndidle);

}}

;;$$ é o contador de argumentos de um comando escrever

Page 66: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Programação para o não-terminal Programação para o não-terminal CmdEscreverCmdEscrever::

CmdEscreverCmdEscrever : ESCREVER ABPAR {- - - - -} ListEscr : ESCREVER ABPAR {- - - - -} ListEscr

{{

opnd1.tipo = INTOPND;opnd1.tipo = INTOPND;

opnd1.atr.valint = $4;opnd1.atr.valint = $4;

GeraQuadrupla (OPWRITE, opnd1, opndidle, GeraQuadrupla (OPWRITE, opnd1, opndidle, opndidle);opndidle);

}}

FPAR PVIRG {printf (") ;\n");}FPAR PVIRG {printf (") ;\n");}

;;

No arquivo inter022013.dat, tirar o comentário dos comandos ler e escrever e rodar

Page 67: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Exercício 4.8: Exercício 4.8: Inserir quádruplas para Inserir quádruplas para indexaçãoindexação

Sejam as seguintes declarações e comandos:Sejam as seguintes declarações e comandos:

int i, j, k, A[6,5]; int i, j, k, A[6,5];

i := 4; j := 3;i := 4; j := 3;

k := A[i,j-2] + 7;k := A[i,j-2] + 7;

A[10-i,2*j+3] := i + j * k;A[10-i,2*j+3] := i + j * k;

ler (i, j, A[i+j,2*i-j]);ler (i, j, A[i+j,2*i-j]);

Acesso a um elemento genérico Acesso a um elemento genérico A[i,j]:A[i,j]:

Uma vez conhecido o Uma vez conhecido o endereço inicialendereço inicial da matriz da matriz AA, é necessário , é necessário localizarlocalizar o elemento o elemento A[i,j]A[i,j]

Seja a seguir o mapa de Seja a seguir o mapa de A[6,5] A[6,5] na memória:na memória:

  

Page 68: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Seja Seja mm o número de linhas o número de linhas e e nn o número de colunas da o número de colunas da matriz matriz AA

O endereço do elemento O endereço do elemento A[i,j] A[i,j] é dado pela fórmula:é dado pela fórmula:

Ender (A) + i * n + jEnder (A) + i * n + j

Para Para m := 6m := 6, , n := 5n := 5, o , o endereço de endereço de A[4,3]A[4,3] é é

Ender (A) + 23Ender (A) + 23

  

Page 69: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

No programa, cada No programa, cada índiceíndice pode ser uma pode ser uma expressão expressão inteirainteira

Calcula-se o valor de cada Calcula-se o valor de cada índiceíndice, empilhando-o numa , empilhando-o numa pilha de índicespilha de índices

Isso pode ser feito pela Isso pode ser feito pela execução de uma execução de uma quádruplaquádrupla de operador de operador INDIND::

IND, i , ---- , ----IND, i , ---- , ----

IND, j , ---- , ----IND, j , ---- , ----

  

Page 70: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Calcula-se o endereço de Calcula-se o endereço de A[i,j]A[i,j], , usando uma quádrupla de usando uma quádrupla de operador operador INDEXINDEX::

INDEX , A , 2 , temp1INDEX , A , 2 , temp1

Sua Sua execuçãoexecução consiste em: consiste em: Pegar as Pegar as dimensõesdimensões e o e o

endereçoendereço de de AA na tabela de na tabela de símbolossímbolos

Desempilhar Desempilhar dois índicesdois índices Calcular o Calcular o endereçoendereço, ,

colocando-o na variável colocando-o na variável temp1temp1

A variável A variável temp1 temp1 é portanto um é portanto um ponteiroponteiro

  

Page 71: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Quando o elemento Quando o elemento A[i,j]A[i,j] está numa está numa expressãoexpressão, necessita-se do , necessita-se do conteúdoconteúdo do local do local apontado por apontado por temp1temp1

Para isso, pode-se usar uma quádrupla de Para isso, pode-se usar uma quádrupla de operador operador CONTAPONTCONTAPONT::

CONTAPONT , temp1 , ---- , temp2CONTAPONT , temp1 , ---- , temp2

  

int i, j, k, A[6,5];

i := 4; j := 3;

k := A[i,j-2] + 7;

A[10-i,2*j+3] := i + j * k;

ler (i, j, A[i+j,2*i-j]);

temp2 recebe o conteúdo do local apontado por temp1

Page 72: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Quando o elemento Quando o elemento A[i,j]A[i,j] vai receber uma vai receber uma atribuição, o local apontado por atribuição, o local apontado por temp1temp1 é que é que vai receber issovai receber isso

Então, pode-se usar uma quádrupla de Então, pode-se usar uma quádrupla de operador operador ATRIBPONTATRIBPONT::

ATRIBPONT , tempexpr , ---- , temp1ATRIBPONT , tempexpr , ---- , temp1

  

int i, j, k, A[6,5];

i := 4; j := 3;

k := A[i,j-2] + 7;

A[10-i,2*j+3] := i + j * k;

ler (i, j, A[i+j,2*i-j]);

O local apontado por temp1 recebe o conteúdo de tempexpr

Page 73: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Quando o elemento Quando o elemento A[i,j]A[i,j] vai receber um valor vai receber um valor lido:lido:

O valor lido é guardado numa O valor lido é guardado numa temporáriatemporária O local apontado por O local apontado por temp1temp1 recebe o recebe o

valor dessa temporáriavalor dessa temporária

  

É conveniente colocar a leitura do elemento de uma variável indexada numa quádrupla separada:

Duas quádruplas OPREAD

int i, j, k, A[6,5];

i := 4; j := 3;

k := A[i,j-2] + 7;

A[10-i,2*j+3] := i + j * k;

ler (i, j, A[i+j,2*i-j]);

PARAM , tempread , ---- , ----OPREAD , 1 , ---- , ----ATRIBPONT , tempread , ---- , temp1

Page 74: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

Exemplo: Exemplo: seja o seguinte programa:seja o seguinte programa:

programa teste; programa teste;

varvar

int i, j, k, A[10,10]; int i, j, k, A[10,10];

{{

i := 7; j := 5;i := 7; j := 5;

k := A[i-3,j+2] + 5;k := A[i-3,j+2] + 5;

A[10-i,9-j] := i + j * k;A[10-i,9-j] := i + j * k;

ler (i, j, A[2,3], k);ler (i, j, A[2,3], k);

ler (A[1,2]);ler (A[1,2]);

}}

  

A seguir suas possíveis quádruplas

Page 75: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

programa teste;programa teste;

varvar

int i, j, k, A[10,10];int i, j, k, A[10,10];

1) OPENMOD, (MODULO, teste), (IDLE), (IDLE)1) OPENMOD, (MODULO, teste), (IDLE), (IDLE)

{{

i := 7; j := 5;i := 7; j := 5;

2) ATRIB, (INT, 7), (IDLE), (VAR, i)2) ATRIB, (INT, 7), (IDLE), (VAR, i)

3) ATRIB, (INT, 5), (IDLE), (VAR, j)3) ATRIB, (INT, 5), (IDLE), (VAR, j)

  

Page 76: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

k := A[i-3,j+2] + 5;k := A[i-3,j+2] + 5;

4) MENOS, (VAR, i), (INT, 3), (VAR, ##1)4) MENOS, (VAR, i), (INT, 3), (VAR, ##1)

5) IND, (VAR, ##1), (IDLE), (IDLE)5) IND, (VAR, ##1), (IDLE), (IDLE)

6) MAIS, (VAR, j), (INT, 2), (VAR, ##2)6) MAIS, (VAR, j), (INT, 2), (VAR, ##2)

7) IND, (VAR, ##2), (IDLE), (IDLE)7) IND, (VAR, ##2), (IDLE), (IDLE)

8) INDEX, (VAR, A), (INT, 2), (VAR, ##3)8) INDEX, (VAR, A), (INT, 2), (VAR, ##3)

9) CONTAPONT, (VAR, ##3), (IDLE), (VAR, ##4)9) CONTAPONT, (VAR, ##3), (IDLE), (VAR, ##4)

10) MAIS, (VAR, ##4), (INT, 5), (VAR, ##5)10) MAIS, (VAR, ##4), (INT, 5), (VAR, ##5)

11) ATRIB, (VAR, ##5), (IDLE), (VAR, k)11) ATRIB, (VAR, ##5), (IDLE), (VAR, k)

  

Page 77: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

A[10-i,9-j] := i + j * k;A[10-i,9-j] := i + j * k;

12) MENOS, (INT, 10), (VAR, i), (VAR, ##6)12) MENOS, (INT, 10), (VAR, i), (VAR, ##6)

13) IND, (VAR, ##6), (IDLE), (IDLE)13) IND, (VAR, ##6), (IDLE), (IDLE)

14) MENOS, (INT, 9), (VAR, j), (VAR, ##7)14) MENOS, (INT, 9), (VAR, j), (VAR, ##7)

15) IND, (VAR, ##7), (IDLE), (IDLE)15) IND, (VAR, ##7), (IDLE), (IDLE)

16) INDEX, (VAR, A), (INT, 2), (VAR, ##8)16) INDEX, (VAR, A), (INT, 2), (VAR, ##8)

17) MULT, (VAR, j), (VAR, k), (VAR, ##9)17) MULT, (VAR, j), (VAR, k), (VAR, ##9)

18) MAIS, (VAR, i), (VAR, ##9), (VAR, ##10)18) MAIS, (VAR, i), (VAR, ##9), (VAR, ##10)

19) ATRIBPONT, (VAR, ##10), (IDLE), (VAR, ##8)19) ATRIBPONT, (VAR, ##10), (IDLE), (VAR, ##8)

  

Page 78: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

ler (i, j, A[2,3], k);ler (i, j, A[2,3], k);

20) PARAM, (VAR, i), (IDLE), (IDLE)20) PARAM, (VAR, i), (IDLE), (IDLE)

21) PARAM, (VAR, j), (IDLE), (IDLE)21) PARAM, (VAR, j), (IDLE), (IDLE)

22) READ, (INT, 2), (IDLE), (IDLE)22) READ, (INT, 2), (IDLE), (IDLE)

23) IND, (INT, 2), (IDLE), (IDLE)23) IND, (INT, 2), (IDLE), (IDLE)

24) IND, (INT, 3), (IDLE), (IDLE)24) IND, (INT, 3), (IDLE), (IDLE)

25) INDEX, (VAR, A), (INT, 2), (VAR, ##11)25) INDEX, (VAR, A), (INT, 2), (VAR, ##11)

26) PARAM, (VAR, ##12), (IDLE), (IDLE)26) PARAM, (VAR, ##12), (IDLE), (IDLE)

27) READ, (INT, 1), (IDLE), (IDLE)27) READ, (INT, 1), (IDLE), (IDLE)

28) ATRIBPONT, (VAR, ##12), (IDLE), (VAR, ##11)28) ATRIBPONT, (VAR, ##12), (IDLE), (VAR, ##11)

29) PARAM, (VAR, k), (IDLE), (IDLE)29) PARAM, (VAR, k), (IDLE), (IDLE)

30) READ, (INT, 1), (IDLE), (IDLE)30) READ, (INT, 1), (IDLE), (IDLE)

  

Page 79: CES-41 COMPILADORES Aulas Práticas - 2013 Capítulo IV Código Intermediário no Yacc.

ler (A[1,2]);ler (A[1,2]);

}}

31) IND, (INT, 1), (IDLE), (IDLE)31) IND, (INT, 1), (IDLE), (IDLE)

32) IND, (INT, 2), (IDLE), (IDLE)32) IND, (INT, 2), (IDLE), (IDLE)

33) INDEX, (VAR, A), (INT, 2), (VAR, ##13)33) INDEX, (VAR, A), (INT, 2), (VAR, ##13)

34) PARAM, (VAR, ##14), (IDLE), (IDLE)34) PARAM, (VAR, ##14), (IDLE), (IDLE)

35) READ, (INT, 1), (IDLE), (IDLE)35) READ, (INT, 1), (IDLE), (IDLE)

36) ATRIBPONT, (VAR, ##14), (IDLE), (VAR, ##13)36) ATRIBPONT, (VAR, ##14), (IDLE), (VAR, ##13)