ces 41 compiladores aulas pr ticas 2013 n.
Download
Skip this Video
Loading SlideShow in 5 Seconds..
CES-41 COMPILADORES Aulas Práticas - 2013 PowerPoint Presentation
Download Presentation
CES-41 COMPILADORES Aulas Práticas - 2013

Loading in 2 Seconds...

play fullscreen
1 / 54

CES-41 COMPILADORES Aulas Práticas - 2013 - PowerPoint PPT Presentation


  • 99 Views
  • Uploaded on

CES-41 COMPILADORES Aulas Práticas - 2013. Capítulo V Interpretação do Código Intermediário. Código intermediário para linguagens sem subprogramas :. Interpretação: Colocar um ponteiro na 1ª quádrupla executável

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'CES-41 COMPILADORES Aulas Práticas - 2013' - harsha


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.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
ces 41 compiladores aulas pr ticas 2013

CES-41 COMPILADORESAulas Práticas - 2013

Capítulo V

Interpretação do Código Intermediário

slide2
Código intermediário para linguagens sem subprogramas:

Interpretação:

Colocar um ponteiro na 1ª quádrupla executável

Executar cada quádrupla, sequencialmente, até encontrar aquela de operador OPEXIT

As quádruplas de desvio alteram a sequência

quad

slide3
Local para valores das variáveis (temporárias ou não):

Na tabela de símbolos:

Deve-se acrescentar os seguintes campos emcelsimb:

dims

cadeia tid tvar inic ref array ndims

- - - - - - - - - - - - - - - - - - - - - valint valfloat valchar vallogic

Poderia ser usada union

int *valint;

float *valfloat;

char *valchar, *vallogic;

Espaço para estes ponteiros serão alocados na execução da quádrupla OPENMOD

slide4
Exemplo: sejam as declarações

int x; real y; int A[4,3]; real B[5];

dims

dims

cadeia tid tvar inic ref array ndims

- - - - - - - - - - - - - - - - - - - valint valfloat valchar vallogic

cadeia tid tvar inic ref array ndims

- - - - - - - - - - - - - - - - - - - valint valfloat valchar vallogic

A v i s 2 # 4 3 ? ? ?

B v r s 1 # 5 ? ? ?

Alocações na execução de OPENMOD

dims

cadeia tid tvar inic ref array ndims

- - - - - - - - - - - - - - - - - - valint valfloat valchar vallogic

x v i n ? ? ?

dims

cadeia tid tvar inic ref array ndims

- - - - - - - - - - - - - - - - - - valint valfloat valchar vallogic

y v r n ? ? ?

slide5
Programa 5.1: Esqueleto do interpretador para a gramática das aulas de lab

Arquivos: pret012013.y, pret012013.l e pret012013.dat

A seguir, o estado inicial da função principal do interpretador, no final do arquivo pret012013.y

A ser completada durante a aula e durante a execução do projeto

slide6
voidInterpCodIntermed () {

quadruplaquad, quadprox; char encerra;

printf ("\n\nINTERPRETADOR:\n");

encerra = FALSE;

quad = codintermed->prox->listquad->prox;

while (! encerra) {

printf ("\n%4d) %s", quad->num,

nomeoperquad[quad->oper]);

quadprox = quad->prox;

switch (quad->oper) {

case OPEXIT: encerra = TRUE; break;

}

if (! encerra) quad = quadprox;

}

printf ("\n");

}

quad

slide7
Definição do operador de quádrupla OPEXIT:

#define OPEXIT 24

Para guardar valores das variáveis, cada célula da tabela de símbolos terá os seguintes campos:

int *valint;

float *valfloat;

char *valchar, *vallogic;

Espaço para estes ponteiros serão alocados na execução da quádrupla OPENMOD

slide8
Protótipos de algumas funções para o interpretador (outras deverão ser construídas na elaboração do projeto):

voidInterpCodIntermed (void);

voidAlocaVariaveis (void);

voidExecQuadWrite (quadrupla);

voidExecQuadMais (quadrupla);

voidExecQuadLT (quadrupla);

void ExecQuadAtrib (quadrupla);

void ExecQuadRead (quadrupla);

slide9
Na produção do não-terminal Prog:

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

DeclsCmdComp {

GeraQuadrupla (OPEXIT, opndidle, opndidle, opndidle);

VerificaInicRef ();

ImprimeTabSimb ();

ImprimeQuadruplas ();

InterpCodIntermed ();

}

;

Rodar flex, yacc, gcc e executável

A seguir, o arquivo de dados

slide10
programa teste;

var

int a, b, c, i, j; real k; logic b1;

int A[5,4];

{

escrever ("Valor 1: ", 14, "; Valor 2: ", 15.2, "; Valor 3: ", verdade);

escrever ("Valor de 3+4: ", 3+4);

a := 1;

b := 2;

i := 3;

j := 4;

c := a + b + i + j + 20;

k := 12.6;

b1 := verdade;

escrever ("c = ", c, "; k = ", k, "; b1 = ", b1, ";");

slide11
i := 4; j := 5; b1 := verdade;

se (b1) {i := j + 6;} senao {i := i + 15;}

escrever ("i = ", i);

i := 4; j := 5; b1 := verdade;

enquanto (b1) {i := i + j; b1 := falso;}

escrever ("i = ", i);

i := 3;

k := 20.3;

escrever ("i = ", i, "; k = ", k);

/* enquanto (i < k) {

i := i + 4;

escrever ("i = ", i, "; k = ", k);

} */

escrever ("Valor de i+k: ", i+k);

}

slide12
Exercício 5.1: Execução da quádrupla OPENMOD

No switch da função InterpCodIntermed:

case OPENMOD: AlocaVariaveis (); break;

Função AlocaVariáveis (já tem protótipo):

Percorre todas as classes da TabSimb

Para cada classe, visita todas as células

Para cada célula de tipo IDVAR, aloca espaço para o valor da variável correspondente

É preciso examinar o tipo e a dimensão da variável

slide13
Exemplo: sejam as declarações

int x; real A[5,4];

dims

cadeia tid tvar inic ref array ndims

- - - - - - - - - - - - - - - - - - - valint valfloat valchar vallogic

A v r s 3 # 5 4 ? ? ?

dims

- - - - - - - - - - - - - - - - - - - valint valfloat valchar vallogic

cadeia tid tvar inic ref array ndims

x v i n ? ? ?

Apenas um elemento inteiro alocado para x

5*4 = 20 elementos reais alocados para A

slide14
voidAlocaVariaveis () {

simbolo s; intnelemaloc, i, j;

printf ("\n\t\tAlocando as variaveis:");

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

if (tabsimb[i]) {

for (s = tabsimb[i]; s != NULL; s = s->prox){

if (s->tid == IDVAR) {

nelemaloc = 1;

if (s->array)

for (j = 1; j <= s->ndims; j++) nelemaloc *= s->dims[j];

switch (s->tvar) {

case INTEGER:

s->valint = malloc (nelemaloc * sizeof (int)); break;

case FLOAT:

s->valfloat = malloc (nelemaloc * sizeof (float)); break;

case CHAR:

s->valchar = malloc (nelemaloc * sizeof (char)); break;

case LOGICAL:

s->vallogic = malloc (nelemaloc * sizeof (char)); break;

}

printf ("\n\t\t\t%s: %d elemento(s) alocado(s) ", s->cadeia, nelemaloc);

}

}

}

}

nelemaloc: número de elementos alocados para cada variável

dims

Executar e verificar a alocação das variáveis na execução de OPENMOD

cadeia --------- ndims

- - - - - - - - - - - - - - - - - - - valint valfloat valchar vallogic

x ------- ? ? ?

s

slide15
Exercício 5.2: Execução da quádrupla PARAM

Exemplo: seja o comando

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

Suas quádruplas:

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

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

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

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

5) PARAM, (VAR, c), (IDLE), (IDLE)

6) WRITE, (INT, 4), (IDLE), (IDLE)

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

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

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

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

5) PARAM, (VAR, c), (IDLE), (IDLE)

6) WRITE, (INT, 4), (IDLE), (IDLE)

VAR, c

CADEIA, Valor de c:

VAR, ##1

CADEIA, Valor de a+b:

pilhaoperando (global)

Preenchida pelas 4 quádruplas PARAM

pilhaopndaux

A ser preenchida pela quádrupla WRITE

slide17
Execução da quádrupla:

OPWRITE, (INT, 4), (IDLE), (IDLE)

1) Desempilhar 4 operandos de pilhaoperando, empilhando-os em pilhaopndaux

VAR, c

CADEIA, Valor de c:

VAR, ##1

CADEIA, Valor de a+b:

pilhaoperando (global)

Preenchida pelas 4 quádruplas PARAM

pilhaopndaux

A ser preenchida pela quádrupla WRITE

slide18
Execução da quádrupla:

OPWRITE, (INT, 4), (IDLE), (IDLE)

2) Desempilhar 4 operandos de pilhaopndaux, imprimindo seus atributos

CADEIA, Valor de a+b:

VAR, ##1

CADEIA, Valor de c:

VAR, c

pilhaoperando (global)

Esvaziada pela quádrupla WRITE

pilhaopndaux

Preenchida pela quádrupla WRITE

slide19
Declarações para pilhas de operandos (já no arquivo pret012013.y):

typedefstructnohopndnohopnd;

structnohopnd {

operando opnd;

nohopnd *prox;

};

typedefnohopnd *pilhaoperando;

pilhaoperandopilhaopnd, pilhaopndaux;

slide20
Funções para manipular pilhas de operandos (já têm protótipos):

voidEmpilharOpnd (operando x, pilhaoperando *P) {

nohopnd *temp;

temp = *P;

*P = (nohopnd *) malloc (sizeof (nohopnd));

(*P)->opnd = x; (*P)->prox = temp;

}

voidDesempilharOpnd (pilhaoperando *P) {

nohopnd *temp;

if (! VaziaOpnd (*P)) {

temp = *P; *P = (*P)->prox; free (temp);

}

elseprintf ("\n\tDelecao em pilha vazia\n");

}

slide21
operando TopoOpnd (pilhaoperando P) {

if (! VaziaOpnd (P)) return P->opnd;

elseprintf ("\n\tTopo de pilha vazia\n");

}

voidInicPilhaOpnd (pilhaoperando *P) {

*P = NULL;

}

charVaziaOpnd (pilhaoperando P) {

if (P == NULL) return 1;

elsereturn 0;

}

slide22
Programação para executar quádruplas PARAM

No início da função InterpCodIntermed:

printf ("\n\nINTERPRETADOR:\n");

InicPilhaOpnd (&pilhaopnd);

encerra = FALSO;

quad = codintermed->listquad->prox;

No switch da função InterpCodIntermed:

case PARAM:

EmpilharOpnd (quad->opnd1, &pilhaopnd);

break;

slide23
Exercício 5.3: Execução da quádrupla OPWRITE

Exemplo:

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

A execução compreende os passos:

Inicializar a pilha auxiliar de operandos

Transportar os operandos da pilha oficial para a auxiliar

Desempilhar cada operando da pilha auxiliar, imprimindo seu atributo

slide24
Escrita dos valores dos operandos:

O problema é encontrar o paradeiro do valor a ser impresso

Depende do tipo do operando, que pode ser:

Uma variável

Uma constante inteira, real, caractere, lógica ou cadeia de caracteres

slide25
Se for uma variável, ela pode ser inteira, real, caractere ou lógica:

O valor do operando fica então guardado na TabSimb

dims

cadeia tid tvar inic ref array ndims

- - - - - - - - - - - - - - - - - - - - valint valfloat valchar vallogic

A v r s 3 # 5 4 ? ? ?

dims

cadeia tid tvar inic ref array ndims

- - - - - - - - - - - - - - - - - - - valint valfloat valchar vallogic

x v i n ? ? ?

slide26
Programação para executar quádruplas OPWRITE:

No switch da função InterpCodIntermed:

case OPWRITE: ExecQuadWrite (quad); break;

Função ExecQuadWrite (já tem protótipo):

voidExecQuadWrite (quadruplaquad) {

int i; operando opndaux; pilhaoperandopilhaopndaux;

printf ("\n\t\tEscrevendo: \n\n");

InicPilhaOpnd (&pilhaopndaux);

for (i = 1; i <= quad->opnd1.atr.valint; i++) {

EmpilharOpnd (TopoOpnd (pilhaopnd), &pilhaopndaux);

DesempilharOpnd (&pilhaopnd);

}

slide27
for (i = 1; i <= quad->opnd1.atr.valint; i++) {

opndaux = TopoOpnd (pilhaopndaux);

DesempilharOpnd (&pilhaopndaux);

switch (opndaux.tipo) {

case INTOPND:

printf ("%d", opndaux.atr.valint); break;

case REALOPND:

printf ("%g", opndaux.atr.valfloat); break;

case CHAROPND:

printf ("%c", opndaux.atr.valchar); break;

case LOGICOPND:

if (opndaux.atr.vallogic == 1) printf ("VERDADE");

else printf ("FALSO");

break;

case CADOPND:

printf ("%s", opndaux.atr.valcad);

break ;

slide28
case VAROPND:

switch (opndaux.atr.simb->tvar) {

case INTEGER:

printf ("%d", *(opndaux.atr.simb->valint)); break;

case FLOAT:

printf ("%g",

*(opndaux.atr.simb->valfloat));break;

case LOGICAL:

if (*(opndaux.atr.simb->vallogic) == 1)

printf ("VERDADE");

else printf ("FALSO"); break;

case CHAR:

printf ("%c",

*(opndaux.atr.simb->valchar)); break;

}

break;

}

}

printf ("\n");

}

Executar observando os valores escritos pelas quádruplas OPWRITE

slide29
Exercício 5.4: Execução da quádrupla OPMAIS

Exemplo:

MAIS, (VAR, a), (REAL, 12.5), (VAR, ##1)

O problema agora é encontrar o paradeiro dos elementos a serem somados e onde guardar o resultado da soma

Tudo depende do tipo do operando e da temporária que vai receber o resultado, que podem ser:

Uma variável

Uma constante inteira, real, caractere

slide30
Programação para executar quádruplas OPMAIS:

No switch da função InterpCodIntermed:

case OPMAIS: ExecQuadMais (quad); break;

Função ExecQuadMais (já tem protótipo):

voidExecQuadMais (quadruplaquad) {

int tipo1, tipo2, valint1, valint2;

float valfloat1, valfloat2;

Guardam os valores a serem somados, conforme os tipos

Guardam os tipos dos valores a serem somados

slide31
switch (quad->opnd1.tipo) {

case INTOPND:

tipo1 = INTOPND; valint1 = quad->opnd1.atr.valint; break;

case REALOPND:

tipo1 = REALOPND; valfloat1 = quad->opnd1.atr.valfloat; break;

case CHAROPND:

tipo1 = INTOPND; valint1 = quad->opnd1.atr.valchar; break;

case VAROPND:

switch (quad->opnd1.atr.simb->tvar) {

case INTEGER:

tipo1 = INTOPND;

valint1 = *(quad->opnd1.atr.simb->valint); break;

case FLOAT:

tipo1 = REALOPND;

valfloat1=*(quad->opnd1.atr.simb->valfloat);break;

case CHAR:

tipo1 = INTOPND;

valint1 = *(quad->opnd1.atr.simb->valchar); break;

}

break;

}

slide32
switch (quad->opnd2.tipo) {

case INTOPND:

tipo2 = INTOPND; valint2 = quad->opnd2.atr.valint; break;

case REALOPND:

tipo2 = REALOPND; valfloat2 = quad->opnd2.atr.valfloat; break;

case CHAROPND:

tipo2 = INTOPND; valint2 = quad->opnd2.atr.valchar; break;

case VAROPND:

switch (quad->opnd2.atr.simb->tvar) {

case INTEGER:

tipo2 = INTOPND;

valint2 = *(quad->opnd2.atr.simb->valint); break;

case FLOAT:

tipo2 = REALOPND;

valfloat2=*(quad->opnd2.atr.simb->valfloat);break;

case CHAR:

tipo2 = INTOPND;

valint2=*(quad->opnd2.atr.simb->valchar);break;

}

break;

}

slide33
switch (quad->result.atr.simb->tvar) {

case INTEGER:

*(quad->result.atr.simb->valint) = valint1 + valint2;

break;

case FLOAT:

if (tipo1 == INTOPND && tipo2 == INTOPND)

*(quad->result.atr.simb->valfloat) = valint1 + valint2;

if (tipo1 == INTOPND && tipo2 == REALOPND)

*(quad->result.atr.simb->valfloat) = valint1 + valfloat2;

if (tipo1 == REALOPND && tipo2 == INTOPND)

*(quad->result.atr.simb->valfloat) = valfloat1 + valint2;

if (tipo1 == REALOPND && tipo2 == REALOPND)

*(quad->result.atr.simb->valfloat) = valfloat1 + valfloat2;

break;

}

}

Executar observando os valores escritos de resultados de somas

slide34
Exercício 5.5: Execução da quádrupla OPATRIB

Exemplo: seja a atribuição: b1 := (i+3 >= j-2) && b2

Suasquádruplaspodem ser:

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

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

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

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

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

O problema agora é encontrar o paradeiro do valor a ser atribuído e onde guardá-lo

Tudo depende dos tipos dos operandos envolvidos

slide35
Programação para executar quádruplas OPATRIB:

No switch da função InterpCodIntermed:

case OPATRIB: ExecQuadAtrib (quad); break;

Função ExecQuadAtrib (já tem protótipo):

voidExecQuadAtrib (quadruplaquad) {

int tipo1, valint1;

float valfloat1;

char valchar1, vallogic1;

Guardam os valores a serem atribuídos, conforme os tipos

Guarda o tipo do valor a ser atribuído

slide36
switch (quad->opnd1.tipo) {

case INTOPND:

tipo1 = INTOPND;

valint1 = quad->opnd1.atr.valint; break;

case REALOPND:

tipo1 = REALOPND;

valfloat1 = quad->opnd1.atr.valfloat; break;

case CHAROPND:

tipo1 = CHAROPND;

valchar1 = quad->opnd1.atr.valchar; break;

case LOGICOPND:

tipo1 = LOGICOPND;

vallogic1 = quad->opnd1.atr.vallogic; break;

slide37
case VAROPND:

switch (quad->opnd1.atr.simb->tvar) {

case INTEGER:

tipo1 = INTOPND;

valint1 = *(quad->opnd1.atr.simb->valint); break;

case FLOAT:

tipo1 = REALOPND;

valfloat1=*(quad->opnd1.atr.simb->valfloat);break;

case CHAR:

tipo1 = CHAROPND;

valchar1=*(quad->opnd1.atr.simb->valchar);break;

case LOGICAL:

tipo1 = LOGICOPND;

vallogic1 = *(quad->opnd1.atr.simb->vallogic);

break;

}

break;

}

slide38
switch (quad->result.atr.simb->tvar) {

case INTEGER:

if (tipo1 == INTOPND) *(quad->result.atr.simb->valint) = valint1;

if (tipo1 == CHAROPND)*(quad->result.atr.simb->valint)=valchar1;

break;

case CHAR:

if (tipo1 == INTOPND) *(quad->result.atr.simb->valchar) = valint1;

if (tipo1==CHAROPND)*(quad->result.atr.simb->valchar)=valchar1;

break;

case LOGICAL: *(quad->result.atr.simb->vallogic) = vallogic1; break;

case FLOAT:

if (tipo1 == INTOPND)

*(quad->result.atr.simb->valfloat) = valint1;

if (tipo1 == REALOPND)

*(quad->result.atr.simb->valfloat) = valfloat1;

if (tipo1 == CHAROPND)

*(quad->result.atr.simb->valfloat) = valchar1;

break;

}

}

Executar observando os valores das variáveis que recebem atribuição

slide39
Exercício 5.6: Execução das quádruplas OPJUMP e OPJF

Exemplo: seja o comando enquanto (i < j) i := j + h;

Suas quádruplas:

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

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

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

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

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

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

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

slide40
Nova declaração na função InterpCodIntermed:

charcondicao;

No switch da função InterpCodIntermed:

case OPJUMP: quadprox = quad->result.atr.rotulo; break;

case OPJF:

if (quad->opnd1.tipo == LOGICOPND)

condicao = quad->opnd1.atr.vallogic;

if (quad->opnd1.tipo == VAROPND)

condicao = *(quad->opnd1.atr.simb->vallogic);

if (! condicao)

quadprox = quad->result.atr.rotulo;

break;

Executar observando os desvios efetuados pelos comandos se-senao e enquanto

slide41
Exercício 5.7: Execução da quádrupla OPLT

No switch da função InterpCodIntermed:

case OPLT: ExecQuadLT (quad); break;

Função ExecQuadLT (já tem protótipo):

voidExecQuadLT (quadruplaquad) {

int tipo1, tipo2, valint1, valint2;

float valfloat1, valfloat2;

slide42
switch (quad->opnd1.tipo) {

case INTOPND:

tipo1 = INTOPND; valint1 = quad->opnd1.atr.valint; break;

case REALOPND:

tipo1 = REALOPND; valfloat1=quad->opnd1.atr.valfloat;break;

case CHAROPND:

tipo1 = INTOPND; valint1 = quad->opnd1.atr.valchar; break;

case VAROPND:

switch (quad->opnd1.atr.simb->tvar) {

case INTEGER: tipo1 = INTOPND;

valint1 = *(quad->opnd1.atr.simb->valint);

break;

case FLOAT: tipo1 = REALOPND;

valfloat1 = *(quad->opnd1.atr.simb->valfloat);

break;

case CHAR: tipo1 = INTOPND;

valint1 = *(quad->opnd1.atr.simb->valchar);

break;

}

break;

}

slide43
switch (quad->opnd2.tipo) {

case INTOPND:

tipo2 = INTOPND; valint2 = quad->opnd2.atr.valint; break;

case REALOPND:

tipo2=REALOPND;valfloat2 = quad->opnd2.atr.valfloat;break;

case CHAROPND:

tipo2 = INTOPND;valint2 = quad->opnd2.atr.valchar; break;

case VAROPND:

switch (quad->opnd2.atr.simb->tvar) {

case INTEGER: tipo2 = INTOPND;

valint2 = *(quad->opnd2.atr.simb->valint);

break;

case FLOAT: tipo2 = REALOPND;

valfloat2 = *(quad->opnd2.atr.simb->valfloat);

break;

case CHAR: tipo2 = INTOPND;

valint2 = *(quad->opnd2.atr.simb->valchar);

break;

}

break;

}

slide44
if (tipo1 == INTOPND && tipo2 == INTOPND)

*(quad->result.atr.simb->vallogic) = valint1 < valint2;

if (tipo1 == INTOPND && tipo2 == REALOPND)

*(quad->result.atr.simb->vallogic) = valint1 < valfloat2;

if (tipo1 == REALOPND && tipo2 == INTOPND)

*(quad->result.atr.simb->vallogic) = valfloat1 < valint2;

if (tipo1 == REALOPND && tipo2 == REALOPND)

*(quad->result.atr.simb->vallogic) = valfloat1 < valfloat2;

}

Eliminar os comentários de pret012013.dat e rodar

slide45
Exercício 5.8: Execução da quádrupla READ

Exemplo: seja o comando

ler (a, b, c);

Suas quádruplas:

1) PARAM, (VAR, a), (IDLE), (IDLE

2) PARAM, (VAR, b), (IDLE), (IDLE)

3) PARAM, (VAR, c), (IDLE), (IDLE)

4) READ, (INT, 3), (IDLE), (IDLE)

slide46
1) PARAM, (VAR, a), (IDLE), (IDLE

2) PARAM, (VAR, b), (IDLE), (IDLE)

3) PARAM, (VAR, c), (IDLE), (IDLE)

4) READ, (INT, 3), (IDLE), (IDLE))

VAR, c

VAR, b

VAR, a

pilhaoperando (global)

Preenchida pelas 3 quádruplas PARAM

pilhaopndaux

A ser preenchida pela quádrupla READ

slide47
Execução da quádrupla:

OPREAD, (INT, 3), (IDLE), (IDLE)

1) Desempilhar 3 operandos de pilhaoperando, empilhando-os em pilhaopndaux

VAR, c

VAR, b

VAR, a

pilhaoperando (global)

Preenchida pelas 3 quádruplas PARAM

pilhaopndaux

A ser preenchida pela quádrupla READ

slide48
Execução da quádrupla:

OPREAD, (INT, 3), (IDLE), (IDLE)

2) Desempilhar 3 operandos de pilhaopndaux, lendo valores para seus atributos

VAR, a

VAR, b

VAR, c

pilhaoperando (global)

Esvaziada pela quádrupla READ

pilhaopndaux

Preenchida pela quádrupla READ

slide49
Leitura dos valores dos operandos:

O problema é encontrar o local para guardar o valor lido

É uma variável e depende do tipo, que pode ser:

Inteiro, real, caractere ou lógico

slide50
O valor lido deve ser guardado na TabSimb

dims

cadeia tid tvar inic ref array ndims

- - - - - - - - - - - - - - - - - - - - valint valfloat valchar vallogic

A v r s 3 # 5 4 ? ? ?

dims

cadeia tid tvar inic ref array ndims

- - - - - - - - - - - - - - - - - - - valint valfloat valchar vallogic

x v i n ? ? ?

slide51
Programação para executar quádruplas OPREAD:

No switch da função InterpCodIntermed:

case OPREAD: ExecQuadRead (quad); break;

Os dados de entrada para a execução do programa ficarão num arquivo denominado “entrada”

Nova variável global:

FILE *finput;

Associação com o arquivo de entrada, no início da função InterpCodIntermed:

finput = fopen ("entrada", "r");

slide52
Função ExecQuadRead (já tem protótipo):

voidExecQuadRead (quadruplaquad) {

int i; operando opndaux; pilhaoperandopilhaopndaux;

printf ("\n\t\tLendo: \n");

InicPilhaOpnd (&pilhaopndaux);

for (i = 1; i <= quad->opnd1.atr.valint; i++) {

EmpilharOpnd (TopoOpnd (pilhaopnd), &pilhaopndaux);

DesempilharOpnd (&pilhaopnd);

}

slide53
for (i = 1; i <= quad->opnd1.atr.valint; i++) {

opndaux = TopoOpnd (pilhaopndaux);

DesempilharOpnd (&pilhaopndaux);

switch (opndaux.atr.simb->tvar) {

case INTEGER:

fscanf (finput, "%d", opndaux.atr.simb->valint); break;

case FLOAT:

fscanf (finput, "%g", opndaux.atr.simb->valfloat);break;

case LOGICAL:

fscanf (finput, "%d", opndaux.atr.simb->vallogic); break;

case CHAR:

fscanf (finput, "%c", opndaux.atr.simb->valchar); break;

}

}

}

Executar com o arquivo pret022013.dat

Seu conteúdo e o do arquivo entrada vem a seguir

slide54
Arquivo pret022013.dat:

programa teste;

var

int i, j, k; real x, y; logic a, b; carac m, n;

{

ler (i, j, x, b);

escrever ("i: ", i, "; j: ", j, "; x: ", x, "; b: ", b);

k := i + j;

y := x + 3.4;

a := i < j;

escrever ("k: ", k, "; y: ", y, "; a: ", a);

ler (m);

n := m + ' ';

escrever ("m: ", m, "; n: ", n);

}

Arquivo entrada:

30 20 3.14 1W