CES41 COMPILADORES Aulas Prticas 2016 Captulo V Interpretao
- Slides: 54
CES-41 COMPILADORES Aulas Práticas - 2016 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 Executar cada quádrupla, sequencialmente, até encontrar aquela de operador OPEXIT As quádruplas de desvio alteram a sequência quad
Local para valores das variáveis (temporárias ou não): n Na tabela de símbolos: Poderia ser usada union dims cadeia tid tvar inic ref array ndims n ----------vallogic valint valfloat valchar Deve-se acrescentar os seguintes campos em int *valint; celsimb : float *valfloat; Espaço para estes char *valchar, *vallogic; ponteiros serão alocados na execução da quádrupla OPENMOD
Exemplo: sejam as declarações int x; float y; int A[4][3]; Alocações na execução de float B[5]; OPENMOD dims cadeia tid tvar inic ref array ndims x ? v i n -----------------vallogic valint valfloat valchar ? ? dims cadeia tid tvar inic ref array ndims y ? v r n v i s ? 2 dims ---------vallogic valint valfloat # 4 3 valchar ? ? cadeia tid tvar inic ref array ndims B ? valchar ? cadeia tid tvar inic ref array ndims A ? valfloat v r ? s dims 1 # 5 ---------vallogic valint valfloat ? valchar
Programa 5. 1: Esqueleto do interpretador para a gramática das aulas de lab n Arquivos: pret 012016. y, pret 012016. l e pret 012016. dat n A seguir, o estado inicial da função principal do interpretador, no final do arquivo pret 012016. y - A ser completada durante a aula e durante a execução do projeto
void Interp. Cod. Intermed () { quadrupla quad, quadprox; char encerra; printf ("nn. INTERPRETADOR: n"); encerra = FALSO; quad = codintermed->prox->listquad->prox; while (! encerra) { printf ("n%4 d) %s", quad->num, nomeoperquad[quad->oper]); quadprox = quad->prox; switch (quad->oper) { case OPEXIT: encerra = VERDADE; break; } if (! encerra) quad = quadprox; } printf ("n"); } quad
n Definição do operador de quádrupla OPEXIT: #define n OPEXIT 24 Para guardar valores das variáveis, cada célula da tabela de símbolos terá os seguintes campos: int *valint; float *valfloat; Espaço para estes ponteiros char *valchar, *vallogic; serão alocados na execução da quádrupla OPENMOD
n Protótipos de algumas funções para o interpretador (outras deverão ser construídas na elaboração do projeto): void Interp. Cod. Intermed (void); void Aloca. Variaveis (void); void Exec. Quad. Write (quadrupla); void Exec. Quad. Mais (quadrupla); void Exec. Quad. LT (quadrupla); void Exec. Quad. Atrib (quadrupla); void Exec. Quad. Read (quadrupla);
n Na produção do não-terminal Programa: Programa : {- - -} ID ABCHAVE {- - -} Decl. Locs Cmds FCHAVE { printf ("}n"); Gera. Quadrupla (OPEXIT, opndidle, opndidle); Verifica. Inic. Ref (); Imprime. Tab. Simb (); Imprime. Quadruplas (); Interp. Cod. Intermed (); } ; n Rodar flex, yacc, gcc e executável n A seguir, o arquivo de dados
teste { locais: int a, b, c, i, j; real k; logico b 1; int A[5][4]; comandos: 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; b 1 : = verdade; escrever ("c = ", c, "; k = ", k, "; b 1 = ", b 1, "; ");
i : = 4; j : = 5; b 1 : = verdade; se (b 1) {i : = j + 6; } senao {i : = i + 15; } escrever ("i = ", i); i : = 4; j : = 5; b 1 : = verdade; enquanto (b 1) {i : = i + j; b 1 : = 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); }
Exercício 5. 1: Execução da quádrupla OPENMOD n No switch da função Interp. Cod. Intermed: case OPENMOD: Aloca. Variaveis (); break; n Função Aloca. Variáveis (já tem protótipo): - Percorre todas as classes da Tab. Simb - 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
Exemplo: sejam as declarações int x; float A[5][4]; dims ---------vallogic cadeia tid tvar inic ref array ndims x ? v i n valint valfloat valchar ? ? Apenas um elemento inteiro alocado para x dims cadeia tid tvar inic ref array ndims A ? v r s 2 ---------vallogic # 5 4 ? 5*4 = 20 elementos reais alocados para A valint valfloat ? valchar
void Aloca. Variaveis () { nelemaloc: número de simbolo s; int nelemaloc, i, j; elementos alocados para printf ("ntt. Alocando as variaveis: "); cada variável for (i = 0; i < NCLASSHASH; i++) if (tabsimb[i]) { for (s = tabsimb[i]; s != NULL; s = s->prox){ if (s->tid == IDVAR) { Executar e verificar a alocação das nelemaloc = 1; variáveis na execução de OPENMOD 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 LOGIC: s->vallogic = malloc ( nelemaloc * sizeof (char)); break; } s printf ("nttt%s: %d elemento(s) alocado(s) ", s->cadeia, nelemaloc); } dims } cadeia ----- ndims ---------valint valfloat valchar } vallogic x ------? ? } ?
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); n Suas quádruplas: 1) PARAM, (CADEIA, Valor de a+b: ), (IDLE) 2) MAIS, (VAR, a), (VAR, b), (VAR, ##1) 3) PARAM, (VAR, ##1), (IDLE) 4) PARAM, (CADEIA, Valor de c: ), (IDLE) 5) PARAM, (VAR, c), (IDLE) 6) WRITE, (INT, 4), (IDLE)
1) PARAM, (CADEIA, Valor de a+b: ), (IDLE) 2) MAIS, (VAR, a), (VAR, b), (VAR, ##1) 3) PARAM, (VAR, ##1), (IDLE) 4) PARAM, (CADEIA, Valor de c: ), (IDLE) 5) PARAM, (VAR, c), (IDLE) 6) WRITE, (INT, 4), (IDLE) VAR, c CADEIA, Valor de c: VAR, ##1 CADEIA, Valor de a+b: pilhaoperando (global) pilhaopndaux Preenchida pelas 4 quádruplas PARAM A ser preenchida pela quádrupla WRITE
Execução da quádrupla: OPWRITE, (INT, 4), (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) pilhaopndaux Preenchida pelas 4 quádruplas PARAM A ser preenchida pela quádrupla WRITE
Execução da quádrupla: OPWRITE, (INT, 4), (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) pilhaopndaux Esvaziada pela quádrupla WRITE Preenchida pela quádrupla WRITE
n Declarações para pilhas de operandos (já no arquivo pret 012016. y): typedef struct nohopnd; struct nohopnd { operando opnd; nohopnd *prox; }; typedef nohopnd *pilhaoperando; pilhaoperando pilhaopnd;
n Funções para manipular pilhas de operandos (já têm protótipos): void Empilhar. Opnd (operando x, pilhaoperando *P) { nohopnd *temp; temp = *P; *P = (nohopnd *) malloc (sizeof (nohopnd)); (*P)->opnd = x; (*P)->prox = temp; } void Desempilhar. Opnd (pilhaoperando *P) { nohopnd *temp; if (! Vazia. Opnd (*P)) { temp = *P; *P = (*P)->prox; free (temp); } else printf ("nt. Delecao em pilha vazian"); }
operando Topo. Opnd (pilhaoperando P) { if (! Vazia. Opnd (P)) return P->opnd; else printf ("nt. Topo de pilha vazian"); } void Inic. Pilha. Opnd (pilhaoperando *P) { *P = NULL; } char Vazia. Opnd (pilhaoperando P) { if (P == NULL) return 1; else return 0; }
Programação para executar quádruplas PARAM n No início da função Interp. Cod. Intermed: printf ("nn. INTERPRETADOR: n"); Inic. Pilha. Opnd (&pilhaopnd); encerra = FALSE; quad = codintermed->listquad->prox; n No switch da função Interp. Cod. Intermed: case PARAM: Empilhar. Opnd (quad->opnd 1, &pilhaopnd); break;
Exercício 5. 3: Execução da quádrupla OPWRITE n Exemplo: WRITE, (INT, 4), (IDLE) n 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
Escrita dos valores dos operandos: n O problema é encontrar o paradeiro do valor a ser escrito n Depende do tipo do operando, que pode ser: - Uma variável Uma constante inteira, real, caractere, lógica ou cadeia de caracteres
n Se for uma variável, ela pode ser inteira, real, caractere ou lógica: - O valor do operando fica então guardado na Tab. Simb dims cadeia tid tvar inic ref array ndims x ? v i n valint valfloat valchar ? ? cadeia tid tvar inic ref array ndims A ? ---------vallogic v r ? s 3 dims ----------vallogic # 5 4 valint valfloat ? valchar
Programação para executar quádruplas OPWRITE: n No switch da função Interp. Cod. Intermed: case OPWRITE: Exec. Quad. Write (quad); break; n Função Exec. Quad. Write (já tem protótipo): void Exec. Quad. Write (quadrupla quad) { int i; operando opndaux; pilhaoperando pilhaopndaux; printf ("ntt. Escrevendo: nn"); Inic. Pilha. Opnd (&pilhaopndaux); for (i = 1; i <= quad->opnd 1. atr. valint; i++) { Empilhar. Opnd (Topo. Opnd (pilhaopnd), &pilhaopndaux); Desempilhar. Opnd (&pilhaopnd); }
for (i = 1; i <= quad->opnd 1. atr. valint; i++) { opndaux = Topo. Opnd (pilhaopndaux); Desempilhar. Opnd (&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 ;
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 LOGIC: if (*(opndaux. atr. simb->vallogic) == 1) printf ("VERDADE"); dims else printf ("FALSO"); break; cadeia tid tvar inic ref array ---------valint valfloat valchar ndims vallogic case CHAR: x v i n ? printf ("%c", ? ? *(opndaux. atr. simb->valchar)); break; } Executar observando os valores escritos pelas quádruplas OPWRITE } printf ("n");
Exercício 5. 4: Execução da quádrupla OPMAIS n Exemplo: MAIS, (VAR, a), (REAL, 12. 5), (VAR, ##1) n O problema agora é encontrar o paradeiro dos elementos a serem somados e onde guardar o resultado da soma n 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
Programação para executar quádruplas OPMAIS: n No switch da função Interp. Cod. Intermed: case OPMAIS: Exec. Quad. Mais (quad); break; n Função Exec. Quad. Mais (já tem protótipo): void Exec. Quad. Mais (quadrupla quad) { int tipo 1, tipo 2, valint 1, valint 2; float valfloat 1, valfloat 2; Guardam os tipos dos valores a serem somados Guardam os valores a serem somados, conforme os tipos
switch (quad->opnd 1. tipo) { case INTOPND: tipo 1 = INTOPND; valint 1 = quad->opnd 1. atr. valint; break; case REALOPND: tipo 1 = REALOPND; valfloat 1 = quad->opnd 1. atr. valfloat; break; case CHAROPND: tipo 1 = INTOPND; valint 1 = quad->opnd 1. atr. valchar; break; case VAROPND: switch (quad->opnd 1. atr. simb->tvar) { case INTEGER: tipo 1 = INTOPND; valint 1 = *(quad->opnd 1. atr. simb->valint); break; case FLOAT: tipo 1 = REALOPND; valfloat 1=*(quad->opnd 1. atr. simb>valfloat); break; case CHAR: tipo 1 = INTOPND; valint 1 = *(quad->opnd 1. atr. simb->valchar); break;
switch (quad->opnd 2. tipo) { case INTOPND: tipo 2 = INTOPND; valint 2 = quad->opnd 2. atr. valint; break; case REALOPND: tipo 2 = REALOPND; valfloat 2 = quad->opnd 2. atr. valfloat; break; case CHAROPND: tipo 2 = INTOPND; valint 2 = quad->opnd 2. atr. valchar; break; case VAROPND: switch (quad->opnd 2. atr. simb->tvar) { case INTEGER: tipo 2 = INTOPND; valint 2 = *(quad->opnd 2. atr. simb->valint); break; case FLOAT: tipo 2 = REALOPND; valfloat 2=*(quad->opnd 2. atr. simb>valfloat); break; case CHAR: tipo 2 = INTOPND; valint 2=*(quad->opnd 2. atr. simb>valchar); break;
switch (quad->result. atr. simb->tvar) { case INTEGER: *(quad->result. atr. simb->valint) = valint 1 + valint 2; break; case FLOAT: if (tipo 1 == INTOPND && tipo 2 == INTOPND) *(quad->result. atr. simb->valfloat) = valint 1 + valint 2; if (tipo 1 == INTOPND && tipo 2 == REALOPND) *(quad->result. atr. simb->valfloat) = valint 1 + valfloat 2; if (tipo 1 == REALOPND && tipo 2 == INTOPND) *(quad->result. atr. simb->valfloat) = valfloat 1 + valint 2; if (tipo 1 == REALOPND && tipo 2 == REALOPND) *(quad->result. atr. simb->valfloat) = valfloat 1 + valfloat 2; break; } Executar observando os valores } escritos de resultados de somas
Exercício 5. 5: Execução da quádrupla OPATRIB n Exemplo: seja a atribuição: b 1 : = (i+3 >= j-2) && b 2 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, b 2), (VAR, ##4) ATRIB, (VAR, ##4), (IDLE), (VAR, b 1) n O problema agora é encontrar o paradeiro do valor a ser atribuído e onde guardá-lo n Tudo depende dos tipos dos operandos envolvidos
Programação para executar quádruplas OPATRIB: n No switch da função Interp. Cod. Intermed: case OPATRIB: Exec. Quad. Atrib (quad); break; n Função Exec. Quad. Atrib (já tem protótipo): void Exec. Quad. Atrib (quadrupla quad) { int tipo 1, valint 1; float valfloat 1; char valchar 1, vallogic 1; Guarda o tipo do valor a ser atribuído Guardam os valores a serem atribuídos, conforme os tipos
switch (quad->opnd 1. tipo) { case INTOPND: tipo 1 = INTOPND; valint 1 = quad->opnd 1. atr. valint; break; case REALOPND: tipo 1 = REALOPND; valfloat 1 = quad->opnd 1. atr. valfloat; break; case CHAROPND: tipo 1 = CHAROPND; valchar 1 = quad->opnd 1. atr. valchar; break; case LOGICOPND: tipo 1 = LOGICOPND; vallogic 1 = quad->opnd 1. atr. vallogic; break;
case VAROPND: switch (quad->opnd 1. atr. simb->tvar) { case INTEGER: tipo 1 = INTOPND; valint 1 = *(quad->opnd 1. atr. simb->valint); break; case FLOAT: tipo 1 = REALOPND; valfloat 1=*(quad->opnd 1. atr. simb>valfloat); break; case CHAR: tipo 1 = CHAROPND; valchar 1=*(quad->opnd 1. atr. simb>valchar); break; case LOGIC: tipo 1 = LOGICOPND; vallogic 1 = *(quad->opnd 1. atr. simb->vallogic); break; }
switch (quad->result. atr. simb->tvar) { case INTEGER: if (tipo 1 == INTOPND) *(quad->result. atr. simb->valint) = valint 1; if (tipo 1 == CHAROPND)*(quad->result. atr. simb>valint)=valchar 1; break; case CHAR: if (tipo 1 == INTOPND) *(quad->result. atr. simb->valchar) = valint 1; if (tipo 1==CHAROPND)*(quad->result. atr. simb>valchar)=valchar 1; break; case LOGIC: *(quad->result. atr. simb->vallogic) = vallogic 1; break; case FLOAT: if (tipo 1 == INTOPND) *(quad->result. atr. simb->valfloat) = valint 1; if (tipo 1 == REALOPND) *(quad->result. atr. simb->valfloat) = valfloat 1; Executar observando os valores das if (tipo 1 == CHAROPND) variáveis que recebem atribuição *(quad->result. atr. simb->valfloat) = valchar 1;
Exercício 5. 6: Execução das quádruplas OPJUMP e OPJF n Exemplo: seja o comando enquanto (i < j) i : = j + h; Suas quádruplas: 2) NOP, (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), (ROTULO, 2) 8) NOP, (IDLE), (IDLE)
n Nova declaração na função Interp. Cod. Intermed: char condicao; n No switch da função Interp. Cod. Intermed: case OPJUMP: quadprox = quad->result. atr. rotulo; break; case OPJF: if (quad->opnd 1. tipo == LOGICOPND) condicao = quad->opnd 1. atr. vallogic; if (quad->opnd 1. tipo == VAROPND) condicao = *(quad->opnd 1. atr. simb->vallogic); if (! condicao) quadprox = quad->result. atr. rotulo; break; Executar observando os desvios efetuados pelos comandos if-else e while
Exercício 5. 7: Execução da quádrupla OPLT n No switch da função Interp. Cod. Intermed: case OPLT: Exec. Quad. LT (quad); break; n Função Exec. Quad. LT (já tem protótipo): void Exec. Quad. LT (quadrupla quad) { int tipo 1, tipo 2, valint 1, valint 2; float valfloat 1, valfloat 2;
switch (quad->opnd 1. tipo) { case INTOPND: tipo 1 = INTOPND; valint 1 = quad->opnd 1. atr. valint; break; case REALOPND: tipo 1 = REALOPND; valfloat 1=quad>opnd 1. atr. valfloat; break; case CHAROPND: tipo 1 = INTOPND; valint 1 = quad->opnd 1. atr. valchar; break; case VAROPND: switch (quad->opnd 1. atr. simb->tvar) { case INTEGER: tipo 1 = INTOPND; valint 1 = *(quad->opnd 1. atr. simb->valint); break; case FLOAT: tipo 1 = REALOPND; valfloat 1 = *(quad->opnd 1. atr. simb>valfloat); break; case CHAR: tipo 1 = INTOPND; valint 1 = *(quad->opnd 1. atr. simb->valchar); break; }
switch (quad->opnd 2. tipo) { case INTOPND: tipo 2 = INTOPND; valint 2 = quad->opnd 2. atr. valint; break; case REALOPND: tipo 2=REALOPND; valfloat 2 = quad>opnd 2. atr. valfloat; break; case CHAROPND: tipo 2 = INTOPND; valint 2 = quad->opnd 2. atr. valchar; break; case VAROPND: switch (quad->opnd 2. atr. simb->tvar) { case INTEGER: tipo 2 = INTOPND; valint 2 = *(quad->opnd 2. atr. simb->valint); break; case FLOAT: tipo 2 = REALOPND; valfloat 2 = *(quad->opnd 2. atr. simb>valfloat); break; case CHAR: tipo 2 = INTOPND; valint 2 = *(quad->opnd 2. atr. simb->valchar); break; } break;
if (tipo 1 == INTOPND && tipo 2 == INTOPND) *(quad->result. atr. simb->vallogic) = valint 1 < valint 2; if (tipo 1 == INTOPND && tipo 2 == REALOPND) *(quad->result. atr. simb->vallogic) = valint 1 < valfloat 2; if (tipo 1 == REALOPND && tipo 2 == INTOPND) *(quad->result. atr. simb->vallogic) = valfloat 1 < valint 2; if (tipo 1 == REALOPND && tipo 2 == REALOPND) *(quad->result. atr. simb->vallogic) = valfloat 1 < valfloat 2; } n Eliminar os comentários de pret 012016. dat e rodar
Exercício 5. 8: Execução da quádrupla READ Exemplo: seja o comando ler (a, b, c); n Suas quádruplas: 1) PARAM, (VAR, a), (IDLE 2) PARAM, (VAR, b), (IDLE) 3) PARAM, (VAR, c), (IDLE) 4) READ, (INT, 3), (IDLE)
1) PARAM, (VAR, a), (IDLE 2) PARAM, (VAR, b), (IDLE) 3) PARAM, (VAR, c), (IDLE) 4) READ, (INT, 3), (IDLE)) VAR, c VAR, b VAR, a pilhaoperando (global) pilhaopndaux Preenchida pelas 3 quádruplas PARAM A ser preenchida pela quádrupla READ
Execução da quádrupla: OPREAD, (INT, 3), (IDLE) 1) Desempilhar 3 operandos de pilhaoperando, empilhando-os em pilhaopndaux VAR, c VAR, b VAR, a pilhaoperando (global) pilhaopndaux Preenchida pelas 3 quádruplas PARAM A ser preenchida pela quádrupla READ
Execução da quádrupla: OPREAD, (INT, 3), (IDLE) 2) Desempilhar 3 operandos de pilhaopndaux, lendo valores para seus atributos VAR, a VAR, b VAR, c pilhaoperando (global) pilhaopndaux Esvaziada pela quádrupla READ Preenchida pela quádrupla READ
Leitura dos valores dos operandos: n O problema é encontrar o local para guardar o valor lido n É uma variável e depende do tipo, que pode ser: - Inteiro, real, caractere ou lógico
n O valor lido deve ser guardado na Tab. Simb dims ---------vallogic cadeia tid tvar inic ref array ndims x ? v i n valint valfloat valchar ? ? dims cadeia tid tvar inic ref array ndims A ? v r ? s 3 ----------vallogic # 5 4 valint valfloat ? valchar
Programação para executar quádruplas OPREAD: n No switch da função Interp. Cod. Intermed: case OPREAD: Exec. Quad. Read (quad); break; n Os dados de entrada para a execução do programa ficarão num arquivo denominado “entrada 2016” n Nova variável global: FILE *finput; n Associação com o arquivo de entrada, no início da função Interp. Cod. Intermed: finput = fopen ("entrada 2016", "r");
n Função Exec. Quad. Read (já tem protótipo): void Exec. Quad. Read (quadrupla quad) { int i; operando opndaux; pilhaoperando pilhaopndaux; printf ("ntt. Lendo: n"); Inic. Pilha. Opnd (&pilhaopndaux); for (i = 1; i <= quad->opnd 1. atr. valint; i++) { Empilhar. Opnd (Topo. Opnd (pilhaopnd), &pilhaopndaux); Desempilhar. Opnd (&pilhaopnd); }
for (i = 1; i <= quad->opnd 1. atr. valint; i++) { opndaux = Topo. Opnd (pilhaopndaux); Desempilhar. Opnd (&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 LOGIC: fscanf (finput, "%d", opndaux. atr. simb->vallogic); break; case CHAR: fscanf (finput, "%c", opndaux. atr. simb->valchar); break; } } } Executar com o arquivo pret 022016. dat Seu conteúdo e o do arquivo entrada 2016 vem a seguir
n Arquivo pret 022016. dat: Arquivo entrada 2016: 50 43 3. 14 1 W teste { locais: int i, j, k; real x, y; logico a, b; carac m, n; comandos: 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); }
- Interpretao
- Https://slidetodoc.com/captulo-2-o-sudeste-e-o-sul-do/
- Https://slidetodoc.com/captulo-2-o-sudeste-e-o-sul-do/
- Curso de compiladores
- Ass compilación
- Expresiones regulares compiladores
- Compiladores
- Pero al revés
- Onde estamos e para onde queremos ir projeto de vida
- Campus uhu
- Mis aulas cads
- Aulas virtuales lae
- Exemplo de parecer do avaliador interno
- Aula de discipulado
- Manfrine aulas
- Aulas em haver
- La vida en las aulas jackson
- Ecocentro aulas
- 2016 pearson education inc
- Biology 30 diploma
- Erin kathryn 2016
- Biologia
- Himss 2016 floor plan
- How to show toolbar in word 2016
- Polisitemia vera tanı kriterleri 2016
- Math is funtastic 2016
- 2016 pearson education inc
- 2016 pearson education inc
- Adonis narcissus 2016
- Windows server 2008
- Heaolu arengukava 2016-2023
- Black eyed susan 2016
- Afs 2016:3
- System center operations manager 2016
- Imap terra outlook 2016
- Informe técnico 1466-2017-servir-gpgsc
- Staar released drama
- Microsoft official academic course microsoft word 2016
- Advocaat petitat
- Looking at our school 2016 a quality framework
- 2016.html?site=
- Resolução da see/mg no 2957 de 20 de abril de 2016
- Cad 2016
- Zpg biologie 2016
- द प्रीअचेर्स डॉटर 2016
- Discovering computers 2016
- Dbcc traceon 2861
- Macros in word 2016
- Accuwage 2016
- Para reciclar um motor de potencia eletrica igual a 200w
- Ch3scho
- Ar 670-1 religious accommodation
- Sql server 2016 security features
- Sunshine state books 2016
- Nrg oncology meeting