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

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

CES-41 COMPILADORES Aulas Práticas

Apresentações semelhantes


Apresentação em tema: "CES-41 COMPILADORES Aulas Práticas"— Transcrição da apresentação:

1 CES-41 COMPILADORES Aulas Práticas - 2017
Capítulo V Interpretação do Código Intermediário

2 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

3 Poderia ser usada union
Local para valores das variáveis (temporárias ou não): Na tabela de símbolos: Deve-se acrescentar os seguintes campos em celsimb: Poderia ser usada union cadeia tid tvar inic ref array ndims dims valint valfloat valchar vallogic int *valint; float *valfloat; char *valchar, *vallogic; Espaço para estes ponteiros serão alocados na execução da quádrupla OPENMOD

4 Exemplo: sejam as declarações
int x; float y; int A[4][3]; float B[5]; Alocações na execução de OPENMOD x v i n ? ? ? cadeia tid tvar inic ref array ndims dims valint valfloat valchar vallogic y v r n ? ? ? cadeia tid tvar inic ref array ndims dims valint valfloat valchar vallogic A v i s # ? ? ? cadeia tid tvar inic ref array ndims dims valint valfloat valchar vallogic B v r s # ? ? ? cadeia tid tvar inic ref array ndims dims valint valfloat valchar vallogic

5 Programa 5.1: Esqueleto do interpretador para a gramática das aulas de lab
Arquivos: pret y, pret l e pret dat A seguir, o estado inicial da função principal do interpretador, no final do arquivo pret y A ser completada durante a aula e durante a execução do projeto

6 void InterpCodIntermed () { quadrupla quad, quadprox; char encerra;
printf ("\n\nINTERPRETADOR:\n"); encerra = FALSO; 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 = VERDADE; break; } if (! encerra) quad = quadprox; printf ("\n"); quad

7 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

8 Protótipos de algumas funções para o interpretador (outras deverão ser construídas na elaboração do projeto): void InterpCodIntermed (void); void AlocaVariaveis (void); void ExecQuadWrite (quadrupla); void ExecQuadMais (quadrupla); void ExecQuadLT (quadrupla); void ExecQuadAtrib (quadrupla); void ExecQuadRead (quadrupla);

9 Na produção do não-terminal Prog:
Prog : { } PROGRAM ID SCOLON { } Decls CompStat { GeraQuadrupla (OPEXIT, opndidle, opndidle, opndidle); VerificaInicRef (); ImprimeTabSimb (); ImprimeQuadruplas (); InterpCodIntermed (); } ; Rodar flex, yacc, gcc e executável A seguir, o arquivo de dados

10 program teste; var int a, b, c, i, j; float k; logic b1; int A[5][4]; { write ("Valor 1: ", 14, "; Valor 2: ", 15.2, "; Valor 3: ", true); write ("Valor de 3+4: ", 3+4); a = 1; b = 2; i = 3; j = 4; c = a + b + i + j + 20; k = 12.6; b1 = true; write ("c = ", c, "; k = ", k, "; b1 = ", b1, ";");

11 i = 4; j = 5; b1 = true; if (b1) {i = j + 6;} else {i = i + 15;} write ("i = ", i); while (b1) {i = i + j; b1 = false;} i = 3; k = 20.3; write ("i = ", i, "; k = ", k); /* while (i < k) { i = i + 4; } */ write ("Valor de i+k: ", i+k); }

12 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

13 Exemplo: sejam as declarações int x; float A[5][4];
cadeia tid tvar inic ref array ndims dims valint valfloat valchar vallogic x v i n ? ? ? Apenas um elemento inteiro alocado para x A v r s # ? ? ? cadeia tid tvar inic ref array ndims dims valint valfloat valchar vallogic 5*4 = 20 elementos reais alocados para A

14 nelemaloc: número de elementos alocados para cada variável
void AlocaVariaveis () { simbolo s; int nelemaloc, 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 INTEIRO: s->valint = malloc (nelemaloc * sizeof (int)); break; case REAL: s->valfloat = malloc (nelemaloc * sizeof (float)); break; case CARACTERE: s->valchar = malloc (nelemaloc * sizeof (char)); break; case LOGICO: 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 Executar e verificar a alocação das variáveis na execução de OPENMOD cadeia ndims dims valint valfloat valchar vallogic x ? ? ? s

15 Exercício 5.2: Execução da quádrupla PARAM Exemplo: seja o comando
write ("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)

16 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

17 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

18 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

19 Declarações para pilhas de operandos (já no arquivo pret012017.y):
typedef struct nohopnd nohopnd; struct nohopnd { operando opnd; nohopnd *prox; }; typedef nohopnd *pilhaoperando; pilhaoperando pilhaopnd;

20 Funções para manipular pilhas de operandos (já têm protótipos):
void EmpilharOpnd (operando x, pilhaoperando *P) { nohopnd *temp; temp = *P; *P = (nohopnd *) malloc (sizeof (nohopnd)); (*P)->opnd = x; (*P)->prox = temp; } void DesempilharOpnd (pilhaoperando *P) { if (! VaziaOpnd (*P)) { temp = *P; *P = (*P)->prox; free (temp); else printf ("\n\tDelecao em pilha vazia\n");

21 operando TopoOpnd (pilhaoperando P) {
if (! VaziaOpnd (P)) return P->opnd; else printf ("\n\tTopo de pilha vazia\n"); } void InicPilhaOpnd (pilhaoperando *P) { *P = NULL; char VaziaOpnd (pilhaoperando P) { if (P == NULL) return 1; else return 0;

22 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;

23 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

24 Escrita dos valores dos operandos:
O problema é encontrar o paradeiro do valor a ser escrito Depende do tipo do operando, que pode ser: Uma variável Uma constante inteira, real, caractere, lógica ou cadeia de caracteres

25 Se for uma variável, ela pode ser inteira, real, caractere ou lógica:
O valor do operando fica então guardado na TabSimb cadeia tid tvar inic ref array ndims dims valint valfloat valchar vallogic x v i n ? ? ? A v r s # ? ? ? cadeia tid tvar inic ref array ndims dims valint valfloat valchar vallogic

26 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): void ExecQuadWrite (quadrupla quad) { int i; operando opndaux; pilhaoperando pilhaopndaux; printf ("\n\t\tEscrevendo: \n\n"); InicPilhaOpnd (&pilhaopndaux); for (i = 1; i <= quad->opnd1.atr.valint; i++) { EmpilharOpnd (TopoOpnd (pilhaopnd), &pilhaopndaux); DesempilharOpnd (&pilhaopnd); }

27 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 ("TRUE"); else printf ("FALSE"); break; case CADOPND: printf ("%s", opndaux.atr.valcad); break ;

28 case VAROPND: switch (opndaux.atr.simb->tvar) { case INTEIRO:
printf ("%d", *(opndaux.atr.simb->valint)); break; case REAL: printf ("%g", *(opndaux.atr.simb->valfloat));break; case LOGICO: if (*(opndaux.atr.simb->vallogic) == 1) printf ("TRUE"); else printf ("FALSE"); break; case CARACTERE: printf ("%c", *(opndaux.atr.simb->valchar)); break; } break; printf ("\n"); cadeia tid tvar inic ref array ndims dims valint valfloat valchar vallogic x v i n ? ? ? Executar observando os valores escritos pelas quádruplas OPWRITE

29 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

30 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): void ExecQuadMais (quadrupla quad) { 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

31 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 INTEIRO: tipo1 = INTOPND; valint1 = *(quad->opnd1.atr.simb->valint); break; case REAL: tipo1 = REALOPND; valfloat1=*(quad->opnd1.atr.simb->valfloat);break; case CARACTERE: valint1 = *(quad->opnd1.atr.simb->valchar); break; } break;

32 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 INTEIRO: tipo2 = INTOPND; valint2 = *(quad->opnd2.atr.simb->valint); break; case REAL: tipo2 = REALOPND; valfloat2=*(quad->opnd2.atr.simb->valfloat);break; case CARACTERE: valint2=*(quad->opnd2.atr.simb->valchar);break; } break;

33 switch (quad->result.atr.simb->tvar) {
case INTEIRO: *(quad->result.atr.simb->valint) = valint1 + valint2; break; case REAL: 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; } Executar observando os valores escritos de resultados de somas

34 Exercício 5.5: Execução da quádrupla OPATRIB
Exemplo: seja a atribuição: b1 = (i+3 >= j-2) && b2 Suas quádruplas podem 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

35 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): void ExecQuadAtrib (quadrupla quad) { 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

36 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;

37 case VAROPND: switch (quad->opnd1.atr.simb->tvar) { case INTEIRO: tipo1 = INTOPND; valint1 = *(quad->opnd1.atr.simb->valint); break; case REAL: tipo1 = REALOPND; valfloat1=*(quad->opnd1.atr.simb->valfloat);break; case CARACTERE: tipo1 = CHAROPND; valchar1=*(quad->opnd1.atr.simb->valchar);break; case LOGICO: tipo1 = LOGICOPND; vallogic1 = *(quad->opnd1.atr.simb->vallogic); break; }

38 switch (quad->result.atr.simb->tvar) { case INTEIRO:
if (tipo1 == INTOPND) *(quad->result.atr.simb->valint) = valint1; if (tipo1 == CHAROPND)*(quad->result.atr.simb->valint)=valchar1; break; case CARACTERE: if (tipo1 == INTOPND) *(quad->result.atr.simb->valchar) = valint1; if (tipo1==CHAROPND)*(quad->result.atr.simb->valchar)=valchar1; case LOGICO: *(quad->result.atr.simb->vallogic) = vallogic1; break; case REAL: 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; } Executar observando os valores das variáveis que recebem atribuição

39 Exercício 5.6: Execução das quádruplas OPJUMP e OPJF
Exemplo: seja o comando while i < j do 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)

40 Nova declaração na função InterpCodIntermed: char condicao;
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 if-else e while

41 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): void ExecQuadLT (quadrupla quad) { int tipo1, tipo2, valint1, valint2; float valfloat1, valfloat2;

42 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 INTEIRO: tipo1 = INTOPND; valint1 = *(quad->opnd1.atr.simb->valint); break; case REAL: tipo1 = REALOPND; valfloat1 = *(quad->opnd1.atr.simb->valfloat); case CARACTERE: tipo1 = INTOPND; valint1 = *(quad->opnd1.atr.simb->valchar); }

43 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 INTEIRO: tipo2 = INTOPND; valint2 = *(quad->opnd2.atr.simb->valint); break; case REAL: tipo2 = REALOPND; valfloat2 = *(quad->opnd2.atr.simb->valfloat); case CARACTERE: tipo2 = INTOPND; valint2 = *(quad->opnd2.atr.simb->valchar); }

44 Eliminar os comentários de pret012017.dat e rodar
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 pret dat e rodar

45 Exercício 5.8: Execução da quádrupla READ Exemplo: seja o comando
read (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)

46 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

47 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

48 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

49 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

50 O valor lido deve ser guardado na TabSimb
cadeia tid tvar inic ref array ndims dims valint valfloat valchar vallogic x v i n ? ? ? A v r s # ? ? ? cadeia tid tvar inic ref array ndims dims valint valfloat valchar vallogic

51 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 “entrada2017” Nova variável global: FILE *finput; Associação com o arquivo de entrada, no início da função InterpCodIntermed: finput = fopen ("entrada2017", "r");

52 Função ExecQuadRead (já tem protótipo):
void ExecQuadRead (quadrupla quad) { int i; operando opndaux; pilhaoperando pilhaopndaux; printf ("\n\t\tLendo: \n"); InicPilhaOpnd (&pilhaopndaux); for (i = 1; i <= quad->opnd1.atr.valint; i++) { EmpilharOpnd (TopoOpnd (pilhaopnd), &pilhaopndaux); DesempilharOpnd (&pilhaopnd); }

53 for (i = 1; i <= quad->opnd1.atr.valint; i++) {
opndaux = TopoOpnd (pilhaopndaux); DesempilharOpnd (&pilhaopndaux); switch (opndaux.atr.simb->tvar) { case INTEIRO: fscanf (finput, "%d", opndaux.atr.simb->valint); break; case REAL: fscanf (finput, "%g", opndaux.atr.simb->valfloat);break; case LOGICO: fscanf (finput, "%d", opndaux.atr.simb->vallogic); break; case CARACTERE: fscanf (finput, "%c", opndaux.atr.simb->valchar); break; } Executar com o arquivo pret dat Seu conteúdo e o do arquivo entrada2017 vem a seguir

54 Arquivo pret022017.dat: Arquivo entrada2017: program teste; var
int i, j, k; float x, y; logic a, b; char m, n; { read (i, j, x, b); write ("i: ", i, "; j: ", j, "; x: ", x, "; b: ", b); k = i + j; y = x + 3.4; a = i < j; write ("k: ", k, "; y: ", y, "; a: ", a); read (m); n = m + ' '; write ("m: ", m, "; n: ", n); } Arquivo entrada2017: W


Carregar ppt "CES-41 COMPILADORES Aulas Práticas"

Apresentações semelhantes


Anúncios Google