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

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

CES-41 COMPILADORES Aulas Práticas - 2014 Capítulo III Análise Semântica no Yacc.

Apresentações semelhantes


Apresentação em tema: "CES-41 COMPILADORES Aulas Práticas - 2014 Capítulo III Análise Semântica no Yacc."— Transcrição da apresentação:

1 CES-41 COMPILADORES Aulas Práticas - 2014 Capítulo III Análise Semântica no Yacc

2 Neste capítulo, será vista a construção da tabela de símbolos e a análise semântica para linguagens de programação Neste capítulo, será vista a construção da tabela de símbolos e a análise semântica para linguagens de programação A tabela de símbolos é fundamental para análise semântica e para geração do código intermediário A tabela de símbolos é fundamental para análise semântica e para geração do código intermediário Além disso pode ser devidamente aproveitada durante a interpretação e a construção do código objeto Além disso pode ser devidamente aproveitada durante a interpretação e a construção do código objeto

3 A complexidade das linguagens pode ser abordada progressivamente: 1.Inicialmente sem subprogramas, só variáveis escalares e comandos de atribuição 2.Acrescenta-se comandos condicionais, repetitivos e de entrada e saída 3.Acrescenta-se variáveis indexadas 4.Acrescenta-se subprogramas e variáveis globais 5.Acrescenta-se blocos e aninhamento de subprogramas 6.Acrescenta-se estruturas e ponteiros, etc. Abordagem do projeto

4 Estrutura de dados para a tabela de símbolos: Será usada a estrutura de hashing aberto Será usada a estrutura de hashing aberto Função para o hashing: Função para o hashing:Onde: – NCLASSHASH é o número de classes. – n é o número de caracteres de x (sem o ‘\0’)

5 Exemplo: Tabela de símbolos (hashing) do programa do fatorial (NCLASSHASH = 23)

6 Declarações para a tabela de símbolos: typedef struct celsimb celsimb; typedef celsimb *simbolo; struct celsimb { char *cadeia; int tid, tvar; logic inic, ref; simbolo prox; }; Variáveis globais: simbolo simb; simbolo tabsimb[NCLASSHASH];

7 Programa 3.1: gramática sem subprogramas, só variáveis escalares e comandos de atribuição A gramática a seguir é uma simplificação daquela da linguagem COMP-ITA 2014 A gramática a seguir é uma simplificação daquela da linguagem COMP-ITA 2014 Seja ela chamada de Sub-Set 2014 Seja ela chamada de Sub-Set 2014

8 Prog:program ID LocDecls Stats LocDecls :  | local { DeclList } DeclList:Declaration | DeclList Declaration Declaration :Type ElemList ; Type: int | float | char | logic ElemList :Elem | ElemList, Elem Elem :ID Stats : statements CompStat CompStat: { StatList } StatList:  | StatList Statement Statement : CompStat | AssignStat AssignStat : Variable = Expression ; Elem: Não-terminal prevendo variáveis indexadas

9 Expression : AuxExpr1 | Expression || AuxExpr1 AuxExpr1 : AuxExpr2 | AuxExpr1 && AuxExpr2 AuxExpr2 : AuxExpr3 | ! AuxExpr3 AuxExpr3 : AuxExpr4 | AuxExpr4 RELOP AuxExpr4 AuxExpr4 :Term | AuxExpr4 ADOP Term Term : Factor | Term MULTOP Factor Factor: Variable | INTCT | FLOATCT | CHARCT | true | false | ~ Factor | ( Expression ) | ( Expression ) Variable: ID Variable: Não-terminal prevendo variáveis indexadas

10 A seguir 3 arquivos fornecidos na aba de ‘Códigos’ da página do professor: A seguir 3 arquivos fornecidos na aba de ‘Códigos’ da página do professor:  tsimb012014.y (analisador sintático)  tsimb012014.l (analisador léxico)  tsimb012014.dat (programa a ser analisado) O primeiro deles contém declarações e funções para montagem de uma tabela de símbolos O primeiro deles contém declarações e funções para montagem de uma tabela de símbolos Depois da sua apresentação, seguem orientações para a montagem da tabela Depois da sua apresentação, seguem orientações para a montagem da tabela

11 a) Arquivo tsimb012014.y %{ /* Inclusao de arquivos da biblioteca de C */ #include #include

12 /* Definicao dos atributos dos atomos operadores */ #define LT 1 #define LE 2 #defineGT3 #defineGE4 #defineEQ5 #defineNE6 #defineMAIS 7 #defineMENOS 8 #defineMULT 9 #defineDIV 10 #defineRESTO 11

13 /* Definicao dos tipos de identificadores */ #define IDPROG1 #define IDVAR2 /* Definicao dos tipos de variaveis */ #define NAOVAR0 #define INTEIRO1 #define LOGICO2 #define REAL3 #define CARACTERE4 /* Definicao de outras constantes */ #defineNCLASSHASH23 #defineVERDADE1 #defineFALSO0 Para o caso de não ser um identificador de variável

14 /* Strings para nomes dos tipos de identificadores */ char *nometipid[3] = {" ", "IDPROG", "IDVAR"}; /* Strings para nomes dos tipos de variaveis */ char *nometipvar[5] = {"NAOVAR", "INTEIRO", "LOGICO", "REAL", "CARACTERE" }; A serem usadas na função para escrever na tela a tabela de símbolos (ImprimeTabSimb)

15 /* Declaracoes para a tabela de simbolos */ typedef struct celsimb celsimb; typedef celsimb *simbolo; struct celsimb { char *cadeia; int tid, tvar; char inic, ref; simbolo prox; }; /* Variaveis globais para a tabela de simbolos e analise semantica */ */ simbolo tabsimb[NCLASSHASH]; simbolo simb;

16 /* Prototipos das funcoes para a tabela de simbolos e analise semantica e analise semantica */ */ void InicTabSimb (void); void ImprimeTabSimb (void); simbolo InsereSimb (char *, int, int); int hash (char *); simbolo ProcuraSimb (char *); void DeclaracaoRepetida (char *); void TipoInadequado (char *); void NaoDeclarado (char *); %}

17 /* Definicao do tipo de yylval e dos atributos dos nao terminais */ %union { char cadeia[50]; int atr, valint; float valreal; char carac; }

18 /* Declaracao dos atributos dos tokens e dos nao-terminais */ %token ID %token CHARCT %token INTCT %token FLOATCT %tokenOR %tokenAND %tokenNOT %token RELOP %token ADOP %token MULTOP %tokenNEG

19 %tokenOPPAR %tokenCLPAR %tokenOPBRACE %tokenCLBRACE %tokenCOMMA %tokenSCOLON %tokenASSIGN %token CHAR %token FALSE %token FLOAT %token INT %token LOCAL %token LOGIC %token PROGRAM %token STATEMENTS %token TRUE %token INVAL %

20 /* Producoes da gramatica: Os terminais sao escritos e, depois de alguns, para alguma estetica, ha mudanca de linha */ Prog:PROGRAM ID {printf ("program %s\n", $2);} LocDecls Stats ; LocDecls : |LOCAL OPBRACE {printf ("local {\n");} DeclList CLBRACE {printf ("}\n");} DeclList CLBRACE {printf ("}\n");} ; DeclList:Declaration | DeclList Declaration ;

21 Declaration :Type ElemList SCOLON {printf (";\n");} ; Type: INT {printf ("int ");} |FLOAT {printf ("float ");} | CHAR {printf ("char ");} | CHAR {printf ("char ");} | LOGIC {printf ("logic ");} | LOGIC {printf ("logic ");} ; ElemList :Elem |ElemList COMMA {printf (", ");} Elem ; ; Elem :ID {printf ("%s ", $1);} ;

22 Stats : STATEMENTS {printf ("statements ");} CompStat ; CompStat: OPBRACE {printf ("{\n");} StatList CLBRACE {printf ("}\n");} ; StatList: | StatList Statement ; Statement : CompStat | AssignStat | AssignStat ; AssignStat : Variable ASSIGN {printf ("= ");} Expression SCOLON {printf (";\n");} ;

23 Expression : AuxExpr1 | Expression OR {printf ("|| ");} AuxExpr1 ; AuxExpr1 : AuxExpr2 | AuxExpr1 AND {printf ("&& ");} AuxExpr2 ; AuxExpr2 : AuxExpr3 | NOT {printf ("! ");} AuxExpr3 ;

24 AuxExpr3 : AuxExpr4 | AuxExpr4 RELOP { switch ($2) { switch ($2) { case LT: printf ("< "); break; case LT: printf ("< "); break; case LE: printf ("<= "); break; case LE: printf ("<= "); break; case EQ: printf ("== "); break; case EQ: printf ("== "); break; case NE: printf ("!= "); break; case NE: printf ("!= "); break; case GT: printf ("> "); break; case GT: printf ("> "); break; case GE: printf (">= "); break; case GE: printf (">= "); break; } } AuxExpr4 } AuxExpr4 ;

25 AuxExpr4 : Term | AuxExpr4 ADOP { switch ($2) { switch ($2) { case MAIS: printf ("+ "); break; case MAIS: printf ("+ "); break; case MENOS: printf ("- "); break; case MENOS: printf ("- "); break; } } Term } Term ; Term : Factor | Term MULTOP { switch ($2) { switch ($2) { case MULT: printf ("* "); break; case MULT: printf ("* "); break; case DIV: printf ("/ "); break; case DIV: printf ("/ "); break; case RESTO: printf ("% "); break; case RESTO: printf ("% "); break; } } Factor } Factor ;

26 Factor: Variable | INTCT {printf ("%d ", $1);} | FLOATCT {printf ("%g ", $1);} | FLOATCT {printf ("%g ", $1);} | CHARCT {printf ("\'%c\' ", $1);} | CHARCT {printf ("\'%c\' ", $1);} | TRUE {printf ("true ");} | TRUE {printf ("true ");} | FALSE {printf ("false ");} | FALSE {printf ("false ");} |NEG {printf ("~ ");} Factor | OPPAR {printf ("( ");} Expression CLPAR {printf (") ");} | OPPAR {printf ("( ");} Expression CLPAR {printf (") ");} ; Variable: ID {printf ("%s ", $1);} ;%

27 /* Inclusao do analisador lexico */ #include "lex.yy.c" /* InicTabSimb: Inicializa a tabela de simbolos */ void InicTabSimb () { int i; for (i = 0; i < NCLASSHASH; i++) tabsimb[i] = NULL; }

28 /* ProcuraSimb (cadeia): Procura cadeia na tabela de simbolos; Caso ela ali esteja, retorna um ponteiro para sua celula; Caso contrario, retorna NULL. */ */ simbolo ProcuraSimb (char *cadeia) { simbolo s; int i; i = hash (cadeia); for (s = tabsimb[i]; (s!=NULL) && strcmp(cadeia, s->cadeia); s = s->prox); return s; }

29 /* InsereSimb (cadeia, tid, tvar): Insere cadeia na tabela de simbolos, com tid como tipo de identificador e com tvar como tipo de variavel; Retorna um ponteiro para a celula inserida */ */ simbolo InsereSimb (char *cadeia, int tid, int tvar) { int i; simbolo aux, s; i = hash (cadeia); aux = tabsimb[i]; s = tabsimb[i] = (simbolo) malloc (sizeof (celsimb)); s->cadeia = (char*) malloc ((strlen(cadeia)+1) * sizeof(char)); strcpy (s->cadeia, cadeia); s->tid = tid;s->tvar = tvar; s->inic = FALSO;s->ref = FALSO; s->prox = aux;return s; }

30 /* hash (cadeia): funcao que determina e retorna a classe de cadeia na tabela de simbolos implementada por hashing */ */ int hash (char *cadeia) { int i, h; for (h = i = 0; cadeia[i]; i++) {h += cadeia[i];} h = h % NCLASSHASH; return h; }

31 /* ImprimeTabSimb: Imprime todo o conteudo da tabela de simbolos */ void ImprimeTabSimb () { int i; simbolo s; printf ("\n\n TABELA DE SIMBOLOS:\n\n"); for (i = 0; i < NCLASSHASH; i++) if (tabsimb[i]) { printf ("Classe %d:\n", i); for (s = tabsimb[i]; s!=NULL; s = s->prox){ printf (" (%s, %s", s->cadeia, nometipid[s->tid]); if (s->tid == IDVAR) printf (", %s, %d, %d", nometipvar[s->tvar], s->inic, s->ref); printf(")\n");}}}

32 /* Mensagens de erros semanticos */ void DeclaracaoRepetida (char *s) { printf ("\n\n***** Declaracao Repetida: %s *****\n\n", s); } void NaoDeclarado (char *s) { printf ("\n\n***** Identificador Nao Declarado: %s *****\n\n", s); } void TipoInadequado (char *s) { printf ("\n\n***** Identificador de Tipo Inadequado: %s *****\n\n", s); }

33 b) Arquivo tsimb012014.l %{ void comentario (void); char tratachar (char *); %} delim[ \t\n\r] ws{delim}+ digito[0-9] letra[A-Za-z] ctint{digito}+ id{letra}({letra}|{digito})* ctreal{digito}+\.{digito}*([Ee][+-]?{digito}+)? carac1\\.|[^\\'] ctcarac'{carac1}' %

34 {ws}{ ;} "/*"{comentario ();} char{return CHAR;} false{return FALSE;} float{return FLOAT;} int{return INT;} local{return LOCAL;} logic{return LOGIC;} program {return PROGRAM;} statements {return STATEMENTS;} true {return TRUE;} {id}{strcpy (yylval.cadeia, yytext); return ID;} {ctcarac}{yylval.carac = tratachar (yytext); return CHARCT;} {ctint}{yylval.valint = atoi(yytext); return INTCT;} {ctreal}{yylval.valreal = atof(yytext); return FLOATCT;}

35 "||"{return OR;} "&&"{return AND;} "!"{return NOT;} "<"{yylval.atr = LT; return RELOP;} "<="{yylval.atr = LE; return RELOP;} ">"{yylval.atr = GT; return RELOP;} ">="{yylval.atr = GE; return RELOP;} "=="{yylval.atr = EQ; return RELOP;} "!="{yylval.atr = NE; return RELOP;} "+"{yylval.atr = MAIS; return ADOP;} "-"{yylval.atr = MENOS; return ADOP;} "*"{yylval.atr = MULT; return MULTOP;} "/"{yylval.atr = DIV; return MULTOP;} "%"{yylval.atr = RESTO; return MULTOP;} "~"{return NEG;}

36 "("{return OPPAR;} ")"{return CLPAR;} "{"{return OPBRACE;} "}"{return CLBRACE;} ";"{return SCOLON;} ","{return COMMA;} "="{return ASSIGN;}.{yylval.carac = yytext[0]; return INVAL;} %

37 /*comentario: le e descarta os comentarios do programa */ void comentario () { char c; int estado; estado = 1; while (estado != 3) { switch (estado) { case 1: c = input (); if (c == EOF) estado = 3; else if (c == '*') estado = 2; break; case 2: c = input (); if (c == EOF || c == '/') estado = 3; else if (c != '*') estado = 1; break; }}}

38 /* tratachar: retorna o codigo ASCII de uma constante do tipo char, eliminando os apostrofos (') e as barras invertidas (\) */ */ char tratachar (char *s) { if (s[1] != '\\') return s[1]; else switch (s[2]) { case 'a': return 7;case '\\': return 92; case 'b': return 8;case 'r': return 13; case '\"': return 34;case 'f': return 12; case 't': return 9;case 'n': return 10; case '0': return 0;case '\'': return 39; case 'v': return 11; default:return s[2]; }} 01234 'K'\0'n'\ 'K'\ S =

39 c) Arquivo tsimb012014.dat program teste local { int i, jjj, h, tb; logic n, m; float v, i; char x, y, z, w; }

40 statements { x = n && m; v = 3.5 * v; y = '@'; v = h % tb; h = jjj % 4.2; { i = jjj*false; jjj = 0; i = jjj*false; jjj = 0;} jjj = n + 1; i = i + 1; { i = !i; i = i + 1 + z; i = !i; i = i + 1 + z; { i = 0; jjj = 0; i = 0; jjj = 0; } jjj = jjjj + teste; jjj = jjjj + teste;}

41 m = v + 2 > x; m = n != true; m = i >= n; n = m == 4; i = i + 1; n = ~ m; n = (!m && n) && (m && !n); i = n / 5; i = (!m && n) / 5; n = (!m || n) && (m || !n); n = (!m || n) && (tb + v); n = (tb + v) || (!m || n); n = (~h + v) * (tb - jjj); i = (!m || n) - 5; } Rodar tudo com o arquivo tsimb012014.dat

42 Exercício 3.1: Inserir no programa 3.1 programação para montar a tabela dos símbolos dos programas analisados e realizar alguns testes semânticos simples, executando as seguintes tarefas: a)Inicializar a tabela de símbolos, anulando os ponteiros de todas as suas classes, e imprimir o conteúdo da tabela de símbolos (que deve ser vazio) b)Inserir o nome do programa na tabela c)Inserir os nomes das variáveis declaradas na tabela, notificando os casos de re-declaração

43 Exercício 3.1: Inserir no programa 3.1 programação para montar a tabela dos símbolos dos programas analisados e realizar alguns testes semânticos simples, executando as seguintes tarefas: d)Verificar se cada identificador usado foi declarado e)Verificar se cada identificador usado de variável é do tipo IDVAR f)Marcar as variáveis referenciadas e inicializadas pelo programa e verificar se todas as variáveis têm essa marca

44 a)Inicializar a tabela de símbolos, anulando os ponteiros de todas as suas classes, e imprimir o conteúdo da tabela de símbolos (que deve ser vazio) Colocar {InicTabSimb ();} no início da 1ª produção Colocar {InicTabSimb ();} no início da 1ª produção Colocar {ImprimeTabSimb ();} no final da mesma produção Colocar {ImprimeTabSimb ();} no final da mesma produção Trocar $2 por $3, na mesma produção Trocar $2 por $3, na mesma produção Prog: PROGRAM ID {printf ("program %s ;\n", $2);} LocDecls Stats {printf ("program %s ;\n", $2);} LocDecls Stats; Rodar com o arquivo tsimb012014.dat

45 b)Inserir o nome do programa na tabela Na produção Prog, na ação depois de ID, depois da chamada de printf, colocar Na produção Prog, na ação depois de ID, depois da chamada de printf, colocar InsereSimb ($3, IDPROG, NAOVAR); Prog: {- - - -} PROGRAM ID {printf ("program %s\n", $3); } {printf ("program %s\n", $3); } LocDecls Stats {- - - -} ; Rodar com o arquivo tsimb012014.dat

46 c)Inserir os nomes das variáveis declaradas na tabela, notificando os casos de re-declaração. Declarar uma nova variável global inteira: tipocorrente Declarar uma nova variável global inteira: tipocorrente Na produção Elem, na ação depois de ID, depois do printf, colocar Na produção Elem, na ação depois de ID, depois do printf, colocar if (ProcuraSimb ($1) != NULL) DeclaracaoRepetida ($1); else InsereSimb ($1, IDVAR, tipocorrente); Elem : ID {printf ("%s ", $1); } ;

47 Nas produções Type, atribuir valor à variável tipocorrente Nas produções Type, atribuir valor à variável tipocorrente tipocorrente = INTEIRO; tipocorrente = REAL; tipocorrente = CARACTERE; tipocorrente = LOGICO; Type : INT {printf (- -); | FLOAT {printf (- -); | CHAR {printf (- -); | LOGIC {printf (- -); }}}}}}}}} Rodar com o arquivo tsimb012014.dat

48 d)Verificar se cada identificador usado foi declarado e)Verificar se cada identificador usado de variável é do tipo IDVAR Na produção Variable, na ação depois de ID, depois do printf, colocar Na produção Variable, na ação depois de ID, depois do printf, colocar simb = ProcuraSimb ($1); if (simb == NULL) NaoDeclarado ($1); else if (simb->tid != IDVAR) TipoInadequado ($1); Variable: ID {printf ("%s ", $1); } ; Rodar com o arquivo tsimb012014.dat

49 f)Marcar as variáveis referenciadas e inicializadas pelo programa e verificar se todas as variáveis têm essa marca Acrescentar o campo simb na declaração %union: Acrescentar o campo simb na declaração %union: /* Definicao dos campos dos tipos dos atributos */ %union { char cadeia[50]; int atr, valint; float valreal; char carac; simbolo simb; simbolo simb;} Isso possibilita que terminais e/ou não-terminais tenham como atributo um ponteiro para uma célula da tabsimb

50 Declarar que o não-terminal Variable tem como atributo o campo simb da %union, colocando antes dos tokens: Declarar que o não-terminal Variable tem como atributo o campo simb da %union, colocando antes dos tokens: %type Variable /* Declaracao dos atributos dos tokens e dos nao- terminais */ %token ID %token CTCARAC %token CTINT

51 Na produção Variable, no final da ação final, colocar: Na produção Variable, no final da ação final, colocar: $$ = simb; Variable: ID { printf - - - - - simb = ProcuraSimb ($1); if - - - - - else if - - - - - }; O atributo do não-terminal Variable é um ponteiro para a célula correspondente a ID na tabsimb

52 Na produção Factor : Variable, colocar, no final, a ação: Na produção Factor : Variable, colocar, no final, a ação: {if ($1 != NULL) $1->ref = VERDADE;} Factor: Variable Na produção AssignStat, colocar, depois de Variable, a ação: Na produção AssignStat, colocar, depois de Variable, a ação: {if ($1 != NULL) $1->inic = $1->ref = VERDADE;} AssignStat : Variable ASSIGN {printf ("<- ");} Expression SCOLON {printf (";\n");} Rodar com o arquivo tsimb012014.dat

53 Fazer uma função VerificaInicRef, que percorra toda a tabsimb, checando e avisando os casos de identificadores não-inicializados e não-referenciados Fazer uma função VerificaInicRef, que percorra toda a tabsimb, checando e avisando os casos de identificadores não-inicializados e não-referenciados – Não esquecer o protótipo Chamar VerificaInicRef antes de ImprimeTabSimb, na ação final da produção Prog Chamar VerificaInicRef antes de ImprimeTabSimb, na ação final da produção Prog Rodar com o arquivo tsimb012014.dat

54 Exercício 3.2: Inserir no programa 3.1 programação para verificar a compatibilidade entre os operadores e os operandos das expressões, de acordo com a tabela

55 Numa produção contendo um operador de expressões, os operandos são não-terminais Numa produção contendo um operador de expressões, os operandos são não-terminais Exemplo: seja a produção Exemplo: seja a produção Term : Term MULTOP Factor No lado direito, Term e Factor representam os operandos de MULTOP No lado direito, Term e Factor representam os operandos de MULTOP É conveniente que esses não-terminais e todos aqueles relacionados com expressões tenham, como atributo o tipo da sub-expressão que eles representam É conveniente que esses não-terminais e todos aqueles relacionados com expressões tenham, como atributo o tipo da sub-expressão que eles representam

56 Acrescentar o campo tipoexpr na declaração %union: Acrescentar o campo tipoexpr na declaração %union: %union { char cadeia[50];int atr, valint; float valreal;char carac; simbolo simb; int tipoexpr; } Declarar que todos os não-terminais relacionados com expressões têm como atributo o campo tipoexpr: Declarar que todos os não-terminais relacionados com expressões têm como atributo o campo tipoexpr: %type Expression AuxExpr1 AuxExpr2 AuxExpr3 AuxExpr4 Term Factor AuxExpr3 AuxExpr4 Term Factor

57 Em cada produção relacionada com expressões, deve ser calculado o atributo do lado esquerdo ($$) Em cada produção relacionada com expressões, deve ser calculado o atributo do lado esquerdo ($$) Nas produções contendo operadores, devem ser feitos testes de compatibilidade Nas produções contendo operadores, devem ser feitos testes de compatibilidade

58 Exemplo: Teste de compatibilidade do operador NEG No não terminal Variable, já está calculado o valor de $$: No não terminal Variable, já está calculado o valor de $$: Variable: ID { printf ("%s ", $1); simb = ProcuraSimb ($1); if (simb == NULL) NaoDeclarado ($1); else if (simb->tid != IDVAR) TipoInadequado ($1); $$ = simb; };

59 Calcular o valor de $$ em todas as produções de Factor e fazer teste de compatibilidade nas produções cabíveis: Calcular o valor de $$ em todas as produções de Factor e fazer teste de compatibilidade nas produções cabíveis: Factor: Variable { if ($1 != NULL) { $1->ref = VERDADE; $$ = $1->tvar; } } | INTCT {printf ("%d ", $1); $$ = INTEIRO; } | FLOATCT {printf ("%g ", $1); $$ = REAL; } | CHARCT {printf ("%c ", $1); $$ = CARACTERE; } | TRUE {printf (“true "); $$ = LOGICO; } | FALSE {printf ("false "); $$ = LOGICO; } Trocar o conteúdo da ação por

60 Calcular o valor de $$ em todas as produções de Factor e fazer teste de compatibilidade nas produções cabíveis: Calcular o valor de $$ em todas as produções de Factor e fazer teste de compatibilidade nas produções cabíveis: Factor: NEG {printf ("~ ");} Factor { if ($3 != INTEIRO && $3 != REAL && $3 != CARACTERE) Incompatibilidade ("Operando improprio para menos unario"); if ($3 == REAL) $$ = REAL; else $$ = INTEIRO; } | OPPAR {printf ("\( ");} Expression CLPAR { printf (") "); $$ = $3; } { printf (") "); $$ = $3; };

61 Criar a função Incompatibilidade e seu protótipo: Criar a função Incompatibilidade e seu protótipo: void Incompatibilidade (char *); void Incompatibilidade (char *s) { printf ("\n\n***** Incompatibilidade: %s *****\n\n", s); } Rodar com o arquivo tsimb012014.dat

62 Exemplo: Teste de compatibilidade do operador MULTOP Calcular o valor de $$ em todas as produções do não-terminal Term e fazer teste de compatibilidade nas produções cabíveis Calcular o valor de $$ em todas as produções do não-terminal Term e fazer teste de compatibilidade nas produções cabíveis

63 Term : Factor /* Default: $$ = $1; */ | Term MULTOP {- - - - -} Factor {switch ($2) { {switch ($2) { case MULT: case DIV: case MULT: case DIV: if ($1 != INTEIRO && $1 != REAL && $1 != CARACTERE if ($1 != INTEIRO && $1 != REAL && $1 != CARACTERE || $4 != INTEIRO && $4!=REAL && $4!=CARACTERE) || $4 != INTEIRO && $4!=REAL && $4!=CARACTERE) Incompatibilidade ("Operando improprio para operador aritmetico"); Incompatibilidade ("Operando improprio para operador aritmetico"); if ($1 == REAL || $4 == REAL) $$ = REAL; if ($1 == REAL || $4 == REAL) $$ = REAL; else $$ = INTEIRO; break; else $$ = INTEIRO; break; case RESTO: case RESTO: if ($1 != INTEIRO && $1 != CARACTERE if ($1 != INTEIRO && $1 != CARACTERE || $4 != INTEIRO && $4 != CARACTERE) || $4 != INTEIRO && $4 != CARACTERE) Incompatibilidade Incompatibilidade ("Operando improprio para operador resto"); ("Operando improprio para operador resto"); $$ = INTEIRO; break; $$ = INTEIRO; break; } } } } ; Exercício: fazer testes para os operadores ADOP, RELOP, NOT, AND e OR Rodar com o arquivo tsimb012014.dat

64 Programa 3.2: Gramática sem subprogramas, com variáveis escalares e indexadas, comandos de atribuição, if, while, read e write Para os exercícios 3.3, 3.4 e 3.5, considerar os arquivos tsimb022014.l e tsimb022014.y da aba de ‘Códigos’ da página do professor Para os exercícios 3.3, 3.4 e 3.5, considerar os arquivos tsimb022014.l e tsimb022014.y da aba de ‘Códigos’ da página do professor Rodar esses programas com o arquivo de dados tsimb012014.dat Rodar esses programas com o arquivo de dados tsimb012014.dat Esses programas já fazem teste de compatibilidade de expressões Esses programas já fazem teste de compatibilidade de expressões

65 Exercício 3.3: Inserir, no programa 3.2, teste para verificar a compatibilidade entre os dois lados dos comandos de atribuição, de acordo com a tabela:

66 AssignStat :Variable { if ($1 != NULL) $1->inic = $1->ref = VERDADE;} if ($1 != NULL) $1->inic = $1->ref = VERDADE;} ASSIGN {printf ("= ");} Expression SCOLON { ASSIGN {printf ("= ");} Expression SCOLON { printf (";\n"); printf (";\n"); if ($1 != NULL) if ($1 != NULL) if ((($1->tvar == INTEIRO || $1->tvar == CARACTERE) && ($5 == REAL || $5 == LOGICO)) || ($1->tvar == REAL && $5 == LOGICO) || ($1->tvar == REAL && $5 == LOGICO) || ($1->tvar == LOGICO && $5 != LOGICO)) Incompatibilidade ("Lado direito de comando de atribuicao improprio"); Incompatibilidade ("Lado direito de comando de atribuicao improprio"); } ; Testar com o arquivo de dados tsimb012014.dat Testar com o arquivo de dados tsimb012014.dat

67 Exercício 3.4: Inserir na gramática do programa 3.2 testes semânticos para as produções dos comandos if, while, read, write que aparecem na linguagem COMP-ITA 2014 Produções: Produções: Statement : CompStat | IfStat | WhileStat | ReadStat | WriteStat | AssignStat | WriteStat | AssignStat IfStat: if Expression then Statement ElseStat ElseStat:  | else Statement WhileStat : while Expression do Statement ReadStat : read ( ReadList ) ; ReadList: ReadElem | ReadList, ReadElem ReadElem: Variable | str Variable WriteStat : write ( WriteList ) ; WriteList: WriteElem | WriteList, WriteElem WriteElem: STRING | Expression | str Variable

68 Statement : CompStat | IfStat | WhileStat | ReadStat | WriteStat | AssignStat | WriteStat | AssignStat IfStat: if Expression then Statement ElseStat ElseStat:  | else Statement WhileStat : while Expression do Statement ReadStat : read ( ReadList ) ; ReadList: ReadElem | ReadList, ReadElem ReadElem: Variable | str Variable WriteStat : write ( WriteList ) ; WriteList: WriteElem | WriteList, WriteElem WriteElem: STRING | Expression | str Variable Marcar as variáveis lidas como inicializadas e referenciadas (tal como no lado esquerdo de atribuição) Marcar as variáveis lidas como inicializadas e referenciadas (tal como no lado esquerdo de atribuição) Não alterar as produções: ReadElem: str Variable e WriteElem: str Variable Elas serão tratadas com as variáveis indexadas

69 Statement : CompStat | IfStat | WhileStat | ReadStat | WriteStat | AssignStat | WriteStat | AssignStat IfStat: if Expression then Statement ElseStat ElseStat:  | else Statement WhileStat : while Expression do Statement ReadStat : read ( ReadList ) ; ReadList: ReadElem | ReadList, ReadElem ReadElem: Variable | str Variable WriteStat : write ( WriteList ) ; WriteList: WriteElem | WriteList, WriteElem WriteElem: STRING | Expression | str Variable Verificar se as expressões dos comandos if e while são lógicas Verificar se as expressões dos comandos if e while são lógicas Testar o programa com o arquivo de dados tsimb022014.dat Testar o programa com o arquivo de dados tsimb022014.dat Abrir o arquivo tsimb022014.dat As variáveis n e num são lidas (inic e ref) Expressões inteiras em comandos if e while

70 Exercício 3.5: Inserir na gramática do programa 3.2 alterações na tabela de símbolos e testes semânticos para as produções que aparecem na linguagem COMP-ITA 2014, envolvendo variáveis indexadas Produções: Produções: Elem:ID | ID [ DimList ] DimList:INTCT | DimList, INTCT ReadElem: Variable | str Variable WriteElem: STRING | Expression | str Variable Variable: ID | ID [ SubscrList ] SubscrList: AuxExpr4 | SubscrList, AuxExpr4 Observar estas produções no arquivo tsimb022014.y Observar estas produções no arquivo tsimb022014.y

71 Na declaração de variáveis indexadas, inserir o nome na tabela de símbolos: Na declaração de variáveis indexadas, inserir o nome na tabela de símbolos: Elem :ID { printf ("%s ", $1); printf ("%s ", $1); if (ProcuraSimb ($1) != NULL) if (ProcuraSimb ($1) != NULL) DeclaracaoRepetida ($1); DeclaracaoRepetida ($1); else else InsereSimb ($1, IDVAR, tipocorrente); InsereSimb ($1, IDVAR, tipocorrente); } | ID OPBRAK {printf ("%s [ ", $1); } DimList CLBRAK {printf ("] ");} CLBRAK {printf ("] ");} ; Copiar

72 No uso de variáveis indexadas, verificar se o nome está na tabela de símbolos: No uso de variáveis indexadas, verificar se o nome está na tabela de símbolos: Variable: ID { printf ("%s ", $1); printf ("%s ", $1); simb = ProcuraSimb ($1); simb = ProcuraSimb ($1); if (simb == NULL) NaoDeclarado ($1); if (simb == NULL) NaoDeclarado ($1); else if (simb->tid != IDVAR) else if (simb->tid != IDVAR) TipoInadequado ($1); $$ = simb; $$ = simb; } | ID OPBRAK { printf ("%s [ ", $1); } SubscrList | ID OPBRAK { printf ("%s [ ", $1); } SubscrList CLBRAK {printf ("] ");} CLBRAK {printf ("] ");} ; Copiar Na segunda produção de Variable, $$ = simb deverá ser corrigido mais adiante

73 Preparar a tabela de símbolos para guardar informações sobre: Preparar a tabela de símbolos para guardar informações sobre:  Número de dimensões de uma variável indexada  Número de elementos de cada dimensão  Tipo de cada elemento Exemplo: para a declaração Exemplo: para a declaração int A[10, 20, 5]: int A[10, 20, 5]: A cadeia IDVAR tid INTEIRO tvar 0 inic 0 ref 1 array 3 ndims 10205.......... dims 012310

74 /* Definicao de outras constantes */ #defineNCLASSHASH23 #defineVERDADE1 #defineFALSO0 #define MAXDIMS10 /* Declaracoes para a tabela de simbolos */ typedef struct celsimb celsimb; typedef celsimb *simbolo; struct celsimb { char *cadeia; int tid, tvar, ndims, dims[MAXDIMS+1] ; char inic, ref, array ; simbolo prox; }; A cadeia IDVAR tid INTEGER tvar 0 inic 0 ref 1 array 3 ndims 10205.......... dims 012310

75 /* ImprimeTabSimb: Imprime todo o conteudo da tabela de simbolos */ void ImprimeTabSimb () { int i; simbolo s; printf ("\n\n TABELA DE SIMBOLOS:\n\n"); for (i = 0; i < NCLASSHASH; i++) if (tabsimb[i]) { printf ("Classe %d:\n", i); for (s = tabsimb[i]; s!=NULL; s = s->prox){ printf (- - - - -); if (s->tid == IDVAR) { printf (- - - - -); if (s->array == VERDADE) { int j; printf (", EH ARRAY\n\tndims = %d, dimensoes:", s->ndims); for (j = 1; j ndims; j++) printf (" %d", s->dims[j]); printf (" %d", s->dims[j]);}}printf(")\n");}}}

76 Alterar toda programação da montagem da tabela de símbolos e de testes semânticos realizados até agora Alterar toda programação da montagem da tabela de símbolos e de testes semânticos realizados até agora A cadeia IDVAR tid INTEGER tvar 0 inic 0 ref 1 array 3 ndims 10205.......... dims 012310

77 Nas declarações das variáveis: Nas declarações das variáveis: Elem :ID { printf ("%s ", $1); if (ProcuraSimb ($1) != NULL) DeclaracaoRepetida ($1); else { simb = InsereSimb ($1, IDVAR, tipocorrente); else { simb = InsereSimb ($1, IDVAR, tipocorrente); simb->array = FALSO; } simb->array = FALSO; }} | ID OPBRAK { printf ("%s [ ", $1); if (ProcuraSimb ($1) != NULL) DeclaracaoRepetida ($1); if (ProcuraSimb ($1) != NULL) DeclaracaoRepetida ($1); else { simb = InsereSimb ($1, IDVAR, tipocorrente); else { simb = InsereSimb ($1, IDVAR, tipocorrente); simb->array = VERDADE; simb->ndims = 0; } simb->array = VERDADE; simb->ndims = 0; } } DimList CLBRAK {printf ("] ");} ; Ainda falta achar as dimensões das variáveis indexadas A cadeia IDVAR tid INTEGER tvar 0 inic 0 ref 1 array 3 ndims 10205.......... dims 012310

78 No dimensionamento das variáveis indexadas, inclusive verificando se a constante inteira usada no dimensionamento de uma variável indexada é positiva: No dimensionamento das variáveis indexadas, inclusive verificando se a constante inteira usada no dimensionamento de uma variável indexada é positiva: DimList : INTCT { printf ("%d ", $1); if ($1 <= 0) Esperado ("Valor inteiro positivo"); if ($1 <= 0) Esperado ("Valor inteiro positivo"); simb->ndims++; simb->dims[simb->ndims] = $1; simb->ndims++; simb->dims[simb->ndims] = $1;} | DimList COMMA INTCT { printf (", %d ", $3); if ($3 <= 0) Esperado ("Valor inteiro positivo"); if ($3 <= 0) Esperado ("Valor inteiro positivo"); simb->ndims++; simb->dims[simb->ndims] = $3; simb->ndims++; simb->dims[simb->ndims] = $3; }; A cadeia IDVAR tid INTEGER tvar 0 inic 0 ref 1 array 3 ndims 10205.......... dims 012310

79 Criar o protótipo: Criar o protótipo: void Esperado (char *); E a função: E a função: void Esperado (char *s) { printf ("\n\n***** Esperado: %s *****\n\n", s); }

80 Na segunda produção do não-terminal Variable, para se determinar o atributo do lado esquerdo, deve ser feita a seguinte alteração: Na segunda produção do não-terminal Variable, para se determinar o atributo do lado esquerdo, deve ser feita a seguinte alteração: Variable: ID { - - - - - $$ = simb; } | ID OPBRAK { printf ("%s [ ", $1); printf ("%s [ ", $1); simb = ProcuraSimb ($1); simb = ProcuraSimb ($1); if (simb == NULL) NaoDeclarado ($1); if (simb == NULL) NaoDeclarado ($1); else if (simb->tid != IDVAR) TipoInadequado ($1); else if (simb->tid != IDVAR) TipoInadequado ($1); $ $ = simb; $ $ = simb; } SubscrList CLBRAK {printf ("] "); $$ = $ 3; } ; É a especificação do atributo de um não-terminal fictício É a especificação do atributo de um não-terminal fictício Rodar o programa com o arquivo tsimb032014.dat, para verificar se as informações foram introduzidas na tabsimb Porque não eliminar isso e não colocar $$ = simb aqui

81 Por default, o atributo de um não-terminal fictício também é do tipo inteiro Por default, o atributo de um não-terminal fictício também é do tipo inteiro Muitas vezes é desejável especificar para ele um dos campos da %union Muitas vezes é desejável especificar para ele um dos campos da %union Isso não pode ser feito por uma declaração %type Isso não pode ser feito por uma declaração %type  %type só declara atributos de não-terminais não-fictícios Para tanto, coloca-se o campo escolhido entre os caracteres ‘ ’, tudo isso logo após o primeiro caractere ‘$’, por exemplo, $ $, $ 1, $ 2 Para tanto, coloca-se o campo escolhido entre os caracteres ‘ ’, tudo isso logo após o primeiro caractere ‘$’, por exemplo, $ $, $ 1, $ 2

82 Exemplo: Seja a seguinte produção: A : B {simb = InsereSimb (- - -);} C {$$ = simb->tvar;} Onde simb é uma variável global e %union {int tipoexpr; simbolo simb;} %type A Por essa programação, deseja-se que o atributo de A seja o tipo da variável da célula apontada por simb Por essa programação, deseja-se que o atributo de A seja o tipo da variável da célula apontada por simb Mas, no processamento do não-terminal C, pode ser que o valor de simb seja alterado, não se realizando o desejado Mas, no processamento do não-terminal C, pode ser que o valor de simb seja alterado, não se realizando o desejado Então a programação na produção deve mudar para Então a programação na produção deve mudar para A : B {$ $ = InsereSimb (- - -);} C {$$ = $ 2->tvar;}

83 Realizar ainda os seguintes testes e ações semânticas: Verificar se as expressões que aparecem nos subscritos das variáveis indexadas são do tipo inteiro ou caractere Verificar se as expressões que aparecem nos subscritos das variáveis indexadas são do tipo inteiro ou caractere Marcar as variáveis indexadas lidas, precedidas pela palavra str, como inicializadas e referenciadas Marcar as variáveis indexadas lidas, precedidas pela palavra str, como inicializadas e referenciadas Marcar as variáveis indexadas escritas, precedidas pela palavra str, como referenciadas Marcar as variáveis indexadas escritas, precedidas pela palavra str, como referenciadas Verificar se uma variável precedida pela palavra str é indexada do tipo char Verificar se uma variável precedida pela palavra str é indexada do tipo char

84 Realizar ainda os seguintes testes e ações semânticas: Verificar se uma variável de tipo escalar tem subscritos Verificar se uma variável de tipo escalar tem subscritos Verificar se uma variável indexada não precedida pela palavra reservada str não tem subscritos Verificar se uma variável indexada não precedida pela palavra reservada str não tem subscritos Verificar se o número de subscritos de uma variável indexada não precedida pela palavra str é igual ao seu número de dimensões declarado Verificar se o número de subscritos de uma variável indexada não precedida pela palavra str é igual ao seu número de dimensões declarado Verificar se o número de subscritos de uma variável indexada precedida pela palavra str é igual ao seu número de dimensões declarado menos 1 Verificar se o número de subscritos de uma variável indexada precedida pela palavra str é igual ao seu número de dimensões declarado menos 1

85 Verificar se as expressões que aparecem nos subscritos das variáveis indexadas são do tipo inteiro ou caractere Verificar se as expressões que aparecem nos subscritos das variáveis indexadas são do tipo inteiro ou caractere Produções para este teste: SubscrList: AuxExpr4 { if ($1 != INTEIRO && $1 != CARACTERE) if ($1 != INTEIRO && $1 != CARACTERE) Incompatibilidade ("Tipo inadequado para subscrito"); Incompatibilidade ("Tipo inadequado para subscrito");} | SubscrList COMMA {printf (", ");} AuxExpr4 { if ($4 != INTEIRO && $4 != CARACTERE) if ($4 != INTEIRO && $4 != CARACTERE) Incompatibilidade ("Tipo inadequado para subscrito"); Incompatibilidade ("Tipo inadequado para subscrito");}; Rodar o programa com o arquivo tsimb032014.dat

86 Marcar as variáveis indexadas lidas, precedidas pela palavra str, como inicializadas e referenciadas Marcar as variáveis indexadas lidas, precedidas pela palavra str, como inicializadas e referenciadas Na produção ReadElem que usa str: Na produção ReadElem que usa str: ReadElem: Variable { if ($1 != NULL) $1->inic = $1->ref = VERDADE; } | STR {printf ("str ");} Variable { if ($3 != NULL) { if ($3 != NULL) { $3->inic = $3->ref = VERDADE;} $3->inic = $3->ref = VERDADE;} } ; Rodar o programa com o arquivo tsimb032014.dat

87 Marcar as variáveis indexadas escritas, precedidas pela palavra str, como referenciadas Marcar as variáveis indexadas escritas, precedidas pela palavra str, como referenciadas Na produção WriteElem que usa str: Na produção WriteElem que usa str: WriteElem: STRING {printf ("\"%s\" ", $1);} | Expression | STR {printf ("str ");} Variable { if ($3 != NULL) { if ($3 != NULL) { $3->ref = VERDADE; } $3->ref = VERDADE; }} ; Rodar o programa com o arquivo tsimb032014.dat

88 Verificar se uma variável precedida pela palavra str é indexada do tipo char Verificar se uma variável precedida pela palavra str é indexada do tipo char Na produção ReadElem que usa str: Na produção ReadElem que usa str: ReadElem: Variable { - - - - - } | STR { - - - - - } Variable { if ($3 != NULL) { if ($3 != NULL) { $3->inic = $3->ref = VERDADE; $3->inic = $3->ref = VERDADE; if ($3->array == FALSO if ($3->array == FALSO || $3->tvar != CARACTERE) Incompatibilidade ("Variavel incompativel com str"); } } ;

89 Verificar se uma variável precedida pela palavra str é indexada do tipo char Verificar se uma variável precedida pela palavra str é indexada do tipo char Na produção WriteElem que usa str: Na produção WriteElem que usa str: WriteElem: STRING {printf ("\"%s\" ", $1);} | Expression | STR {printf ("str ");} Variable { if ($3 != NULL) { if ($3 != NULL) { $3->ref = VERDADE; $3->ref = VERDADE; if ($3->array == FALSO if ($3->array == FALSO || $3->tvar != CARACTERE) Incompatibilidade ("Variavel incompativel com str"); } } ; Rodar o programa com o arquivo tsimb032014.dat

90 Verificar se uma variável de tipo escalar tem subscritos Verificar se uma variável de tipo escalar tem subscritos Na segunda produção de Variable: Na segunda produção de Variable: Variable:ID { - - - - - } | ID OPBRAK { - - - - - } SubscrList | ID OPBRAK { - - - - - } SubscrList CLBRAK { CLBRAK { printf ("] "); $$ = $ 3; printf ("] "); $$ = $ 3; if ($$ != NULL) if ($$ != NULL) if ($$->array == FALSO) if ($$->array == FALSO) NaoEsperado ("Subscrito\(s)"); NaoEsperado ("Subscrito\(s)"); } ;

91 Criar o protótipo: Criar o protótipo: void NaoEsperado (char *); E a função: E a função: void NaoEsperado (char *s) { printf ("\n\n***** Nao Esperado: %s *****\n\n", s); } Rodar o programa com o arquivo tsimb032014.dat

92 Verificar se uma variável indexada não precedida pela palavra reservada str não tem subscritos Verificar se uma variável indexada não precedida pela palavra reservada str não tem subscritos Criar o flag global usastr para sinalizar se uma variável vem precedida da palavra str Criar o flag global usastr para sinalizar se uma variável vem precedida da palavra str Na produção Stats: Na produção Stats: Stats: STATEMENTS { printf ("statements "); usastr = FALSO; } CompStat ;

93 Verificar se uma variável indexada não precedida pela palavra reservada str não tem subscritos Verificar se uma variável indexada não precedida pela palavra reservada str não tem subscritos Na produção ReadElem que usa str: Na produção ReadElem que usa str: ReadElem: Variable { - - - - - } | STR {printf ("str "); usastr = VERDADE; } Variable { if ($3 != NULL) { - - - - - } if ($3 != NULL) { - - - - - } usastr = FALSO; usastr = FALSO; } ;

94 Verificar se uma variável indexada não precedida pela palavra reservada str não tem subscritos Verificar se uma variável indexada não precedida pela palavra reservada str não tem subscritos Na produção WriteElem que usa str: Na produção WriteElem que usa str: WriteElem: STRING { - - - - - } | Expression | STR {printf ("str "); usastr = VERDADE; } Variable { if ($3 != NULL) { - - - - - } if ($3 != NULL) { - - - - - } usastr = FALSO; usastr = FALSO; } ;

95 Verificar se uma variável indexada não precedida pela palavra reservada str não tem subscritos Verificar se uma variável indexada não precedida pela palavra reservada str não tem subscritos Na primeira produção Variable: Na primeira produção Variable: Variable: ID { - - - - - $$ = simb; $$ = simb; if ($$ != NULL) if ($$ != NULL) if ($$->array == VERDADE) if ($$->array == VERDADE) if (usastr == FALSO) if (usastr == FALSO) Esperado ("Subscrito\(s)"); Esperado ("Subscrito\(s)"); } | ID OPBRAK { - - - - - } SubscrList | ID OPBRAK { - - - - - } SubscrList CLBRAK { - - - - - } ; Rodar o programa com o arquivo tsimb032014.dat

96 Verificar se o número de subscritos de uma variável indexada não precedida pela palavra str é igual ao seu número de dimensões declarado Verificar se o número de subscritos de uma variável indexada não precedida pela palavra str é igual ao seu número de dimensões declarado Verificar se o número de subscritos de uma variável indexada precedida pela palavra str é igual ao seu número de dimensões declarado menos 1 Verificar se o número de subscritos de uma variável indexada precedida pela palavra str é igual ao seu número de dimensões declarado menos 1 Deve-se obter o número de subscritos que aparecem depois do nome de uma variável Em seguida, deve-se comparar esse número com o número de dimensões desse nome na tabela de símbolos É necessário verificar se esse nome é precedido pela palavra str

97 O não-terminal SubscrList terá como atributo o número de subscritos: O não-terminal SubscrList terá como atributo o número de subscritos: %union { char cadeia[50]; int atr, valint; float valreal; char carac; simbolo simb; int tipoexpr; int nsubscr; } %type Variable %type Expression AuxExpr1 AuxExpr2 AuxExpr3 AuxExpr4 Term Factor AuxExpr3 AuxExpr4 Term Factor %type SubscrList

98 Nas produções de SubscrList: Nas produções de SubscrList: SubscrList: AuxExpr4 { if ($1 != INTEIRO && $1 != CARACTERE) if ($1 != INTEIRO && $1 != CARACTERE) Incompatibilidade ("Tipo inadequado para subscrito"); Incompatibilidade ("Tipo inadequado para subscrito"); $$ = 1; $$ = 1;} | SubscrList COMMA {printf (", ");} AuxExpr4 { if ($4 != INTEIRO && $4 != CARACTERE) if ($4 != INTEIRO && $4 != CARACTERE) Incompatibilidade ("Tipo inadequado para subscrito"); Incompatibilidade ("Tipo inadequado para subscrito"); $$ = $1 + 1; $$ = $1 + 1;};

99 Nas produções de Variable: Nas produções de Variable: Variable: ID { - - - - - $$ = simb; if ($$ != NULL) if ($$->array == VERDADE) if ($$ != NULL) if ($$->array == VERDADE) if (usastr == FALSO) Esperado ("Subscrito\(s)"); if (usastr == FALSO) Esperado ("Subscrito\(s)"); else if ($$->ndims != 1) Esperado ("Subscrito\(s)"); else if ($$->ndims != 1) Esperado ("Subscrito\(s)");} | ID OPBRAK { - - - - - } SubscrList CLBRAK { - - - - - $$ = $ 3; if ($$ != NULL) if ($$ != NULL) if ($$->array == FALSO) NaoEsperado ("Subscrito\(s)"); if ($$->array == FALSO) NaoEsperado ("Subscrito\(s)"); else if (usastr == FALSO) { else if (usastr == FALSO) { if ($4 != $$->ndims) if ($4 != $$->ndims) Incompatibilidade ("Numero de subscritos incompativel com declaracao"); } Incompatibilidade ("Numero de subscritos incompativel com declaracao"); } else if ($4 != $$->ndims - 1) else if ($4 != $$->ndims - 1) Incompatibilidade ("Numero de subscritos incompativel com declaracao"); Incompatibilidade ("Numero de subscritos incompativel com declaracao"); }; Rodar o programa com o arquivo tsimb032014.dat


Carregar ppt "CES-41 COMPILADORES Aulas Práticas - 2014 Capítulo III Análise Semântica no Yacc."

Apresentações semelhantes


Anúncios Google