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

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

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

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

CES-41 CES-41 COMPILADORESCOMPILADORES

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

Capítulo III Capítulo III

Análise Semântica Análise Semântica no Yaccno Yacc

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

Neste capítulo, será vista a Neste capítulo, será vista a construção da construção da tabela de símbolostabela de símbolos e a e a análise semânticaanálise semântica para linguagens de programaçãopara linguagens de programação

A tabela de símbolos é fundamental para A tabela de símbolos é fundamental para análise semânticaanálise semântica e para geração do e para geração do código código intermediáriointermediário

Além disso pode ser devidamente aproveitada Além disso pode ser devidamente aproveitada durante a durante a interpretaçãointerpretação e a construção do e a construção do código objetocódigo objeto

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

A A complexidadecomplexidade das linguagens pode ser das linguagens pode ser abordada abordada progressivamente:progressivamente:

1.1. Inicialmente sem subprogramas, só Inicialmente sem subprogramas, só variáveis variáveis escalaresescalares e e comandos de atribuiçãocomandos de atribuição

2.2. Acrescenta-se Acrescenta-se comandos condicionaiscomandos condicionais, , repetitivosrepetitivos e de e de entrada e saídaentrada e saída

3.3. Acrescenta-se Acrescenta-se variáveis indexadasvariáveis indexadas

4.4. Acrescenta-se Acrescenta-se subprogramassubprogramas e e variáveis variáveis globaisglobais

5.5. Acrescenta-se Acrescenta-se blocosblocos e e aninhamento de aninhamento de subprogramassubprogramas

6.6. Acrescenta-se Acrescenta-se estruturas estruturas e e ponteirosponteiros, etc., etc.

Abordagem do projeto

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

Estrutura de dados para a tabela de Estrutura de dados para a tabela de símbolos:símbolos:

Será usada a estrutura de Será usada a estrutura de hashing abertohashing aberto

FunçãoFunção para o para o hashinghashing::

Onde: Onde: – NCLASSHASHNCLASSHASH é o é o número de classesnúmero de classes..– nn é o número de caracteres de é o número de caracteres de x x (sem o (sem o ‘\‘\0’0’))

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

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

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

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

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

Programa 3.1: Programa 3.1: gramática sem subprogramas, só gramática sem subprogramas, só variáveis escalares e comandos de atribuiçãovariáveis escalares e comandos de atribuição

A gramática a seguir é uma A gramática a seguir é uma simplificaçãosimplificação daquela da linguagem daquela da linguagem COMP-ITA 2013COMP-ITA 2013

Seja ela chamada de Seja ela chamada de Sub-Set 2013Sub-Set 2013

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

ProgProg :: programa programa ID PVIRGID PVIRG Decls Decls CmdCompCmdComp

DeclsDecls :: | | varvar ListDecl ListDecl

ListDecl ListDecl : : Declaracao | ListDecl DeclaracaoDeclaracao | ListDecl Declaracao

DeclaracaoDeclaracao :: Tipo ListElemDecl Tipo ListElemDecl PVIRGPVIRG

TipoTipo :: intint | | realreal | | caraccarac | | logiclogic

ListElemDecl ListElemDecl :: ElemDecl ElemDecl

|| ListElemDecl ListElemDecl VIRG VIRG ElemDecl ElemDecl

ElemDeclElemDecl :: IDID

CmdComp CmdComp :: ABCHAVABCHAV ListCmds ListCmds FCHAVFCHAV

ListCmdsListCmds :: | ListCmds Comando | ListCmds Comando

ComandoComando :: CmdComp | CmdAtribCmdComp | CmdAtrib

CmdAtribCmdAtrib :: Variavel Variavel ATRIBATRIB Expressao Expressao PVIRGPVIRG

ElemDecl:

Não-terminal prevendo variáveis indexadas

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

Expressao Expressao : : ExprAux1 | Expressao ExprAux1 | Expressao OROR ExprAux1ExprAux1

ExprAux1 ExprAux1 : : ExprAux2 | ExprAux1 ExprAux2 | ExprAux1 ANDAND ExprAux2ExprAux2

ExprAux2 ExprAux2 : : ExprAux3 | ExprAux3 | NOTNOT ExprAux3 ExprAux3

ExprAux3 ExprAux3 : : ExprAux4 | ExprAux4 ExprAux4 | ExprAux4 OPRELOPREL ExprAux4ExprAux4

ExprAux4 ExprAux4 : : Termo | ExprAux4 Termo | ExprAux4 OPADOPAD Termo Termo

TermoTermo : : Fator | Termo Fator | Termo OPMULTOPMULT Fator Fator

FatorFator : : Variavel | Variavel | CTINTCTINT | | CTREALCTREAL

| | CTCARACCTCARAC | | verdadeverdade | | falsofalso

| | NEGNEG Fator Fator

| | ABPARABPAR Expressao Expressao FPARFPAR

VariavelVariavel : : IDID

Variavel:

Não-terminal prevendo variáveis indexadas

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

A seguir A seguir 3 arquivos3 arquivos fornecidos na aba de fornecidos na aba de ‘Códigos’‘Códigos’ da página do professor: da página do professor:

tsimb012013.y tsimb012013.y (analisador sintático)(analisador sintático) tsimb012013.l tsimb012013.l (analisador léxico) (analisador léxico) tsimb012013.dat tsimb012013.dat (programa a ser (programa a ser

analisado)analisado)

O primeiro deles contém O primeiro deles contém declaraçõesdeclarações e e funçõesfunções para montagem de uma para montagem de uma tabela de tabela de símbolossímbolos

Depois da sua Depois da sua apresentaçãoapresentação, seguem , seguem orientaçõesorientações para a para a montagem montagem da tabelada tabela

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

a) Arquivo tsimb012013.ya) Arquivo tsimb012013.y

%{%{

/* Inclusao de arquivos da biblioteca de C /* Inclusao de arquivos da biblioteca de C */*/

#include <stdio.h>#include <stdio.h>

#include <stdlib.h>#include <stdlib.h>

#include <string.h>#include <string.h>

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

/* /* Definicao dos atributos dos atomos operadores Definicao dos atributos dos atomos operadores */*/

#define #define LT LT 11

#define #define LE LE 22

#define#define GTGT 33

#define#define GEGE 44

#define#define EQEQ 55

#define#define NENE 66

#define#define MAIS MAIS 77

#define#define MENOS MENOS 88

#define#define MULT MULT 99

#define#define DIV DIV 1010

#define#define RESTO RESTO 1111

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

/* Definicao dos tipos de identificadores *//* Definicao dos tipos de identificadores */

#define #define IDPROGIDPROG 11#define #define IDVARIDVAR 22

/* Definicao dos tipos de variaveis *//* Definicao dos tipos de variaveis */

#define #define NOTVARNOTVAR 00#define #define INTEGERINTEGER 11#define #define LOGICALLOGICAL 22#define #define FLOATFLOAT 33#define #define CHARCHAR 44

/* Definicao de outras constantes *//* Definicao de outras constantes */

#define#define NCLASSHASHNCLASSHASH 2323#define#define TRUETRUE 11#define#define FALSEFALSE 00

Para o caso de não ser um identificador de variável

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

/* Strings para nomes dos tipos de identificadores /* Strings para nomes dos tipos de identificadores */*/

char *nometipid[3] = {" ", "IDPROG", "IDVAR"};char *nometipid[3] = {" ", "IDPROG", "IDVAR"};

/* Strings para nomes dos tipos de variaveis *//* Strings para nomes dos tipos de variaveis */

char *nometipvar[5] = {"NOTVAR",char *nometipvar[5] = {"NOTVAR",

"INTEGER", "LOGICAL", "FLOAT", "CHAR""INTEGER", "LOGICAL", "FLOAT", "CHAR"

};};

A serem usadas na função para escrever na tela a tabela de símbolos (ImprimeTabSimb)

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

/* Declaracoes para a tabela de simbolos *//* Declaracoes para a tabela de simbolos */

typedef struct celsimb celsimb;typedef struct celsimb celsimb;

typedef celsimb *simbolo;typedef celsimb *simbolo;

struct celsimb {struct celsimb {

char *cadeia;char *cadeia;

int tid, tvar;int tid, tvar;

char inic, ref;char inic, ref;

simbolo prox;simbolo prox;

};};

/* Variaveis globais para a tabela de simbolos e /* Variaveis globais para a tabela de simbolos e analise semanticaanalise semantica

*/*/

simbolo tabsimb[NCLASSHASH];simbolo tabsimb[NCLASSHASH];

simbolo simb;simbolo simb;

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

/*/*

Prototipos das funcoes para a tabela de Prototipos das funcoes para a tabela de simbolossimbolos

e analise semanticae analise semantica

*/*/

void InicTabSimb (void);void InicTabSimb (void);

void ImprimeTabSimb (void);void ImprimeTabSimb (void);

simbolo InsereSimb (char *, int, int);simbolo InsereSimb (char *, int, int);

int hash (char *);int hash (char *);

simbolo ProcuraSimb (char *);simbolo ProcuraSimb (char *);

void DeclaracaoRepetida (char *);void DeclaracaoRepetida (char *);

void TipoInadequado (char *);void TipoInadequado (char *);

void NaoDeclarado (char *);void NaoDeclarado (char *);

%}%}

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

/* Definicao do tipo de yylval e dos atributos dos nao /* Definicao do tipo de yylval e dos atributos dos nao terminais */terminais */

%union {%union {

char cadeia[50];char cadeia[50];

int atr, valint;int atr, valint;

float valreal;float valreal;

char carac;char carac;

}}

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

/* Declaracao dos atributos dos tokens e dos nao-/* Declaracao dos atributos dos tokens e dos nao-terminais */terminais */

%token%token <cadeia><cadeia> IDID

%token%token <carac><carac> CTCARACCTCARAC

%token%token <valint><valint> CTINTCTINT

%token%token <valreal><valreal> CTREALCTREAL

%token%token OROR

%token%token ANDAND

%token%token NOTNOT

%token%token <atr><atr> OPRELOPREL

%token%token <atr><atr> OPADOPAD

%token%token <atr><atr> OPMULTOPMULT

%token%token NEGNEG

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

%token%token ABPARABPAR

%token%token FPARFPAR

%token%token ABCHAVABCHAV

%token%token FCHAVFCHAV

%token%token VIRGVIRG

%token%token PVIRGPVIRG

%token%token ATRIBATRIB

%token%token CARACCARAC

%token%token FALSOFALSO

%token%token INTINT

%token%token LOGICLOGIC

%token%token PROGRAMAPROGRAMA

%token%token REALREAL

%token%token VARVAR

%token%token VERDADEVERDADE

%token%token <carac><carac> INVALINVAL

%%%%

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

/* /* Producoes da gramatica:Producoes da gramatica:

Os terminais sao escritos e, depois de alguns,Os terminais sao escritos e, depois de alguns,

para alguma estetica, ha mudanca de linha para alguma estetica, ha mudanca de linha */*/

ProgProg :: PROGRAMA ID PVIRG PROGRAMA ID PVIRG

{printf ("programa %s ;\n", {printf ("programa %s ;\n", $2);}$2);}

Decls CmdCompDecls CmdComp

;;

Decls Decls ::

|| VAR {printf ("var\n");} VAR {printf ("var\n");} ListDeclListDecl

;;

ListDeclListDecl : : DeclaracaoDeclaracao

|| ListDecl DeclaracaoListDecl Declaracao

;;

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

DeclaracaoDeclaracao :: Tipo ListElemDecl PVIRG Tipo ListElemDecl PVIRG {printf (";\n");}{printf (";\n");}

;;

TipoTipo : : INT {printf ("int ");}INT {printf ("int ");}

| | REAL {printf ("real ");} REAL {printf ("real ");}

| | CARAC {printf ("carac ");}CARAC {printf ("carac ");}

| | LOGIC {printf ("logic ");} LOGIC {printf ("logic ");}

;;

ListElemDecl: ListElemDecl: ElemDeclElemDecl

| | ListElemDecl VIRG {printf (", ListElemDecl VIRG {printf (", ");} ");}

ElemDeclElemDecl

;;

ElemDecl ElemDecl :: ID {printf ("%s ", $1);}ID {printf ("%s ", $1);}

;;

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

CmdCompCmdComp : : ABCHAV {printf ("{\n");} ABCHAV {printf ("{\n");} ListCmdsListCmds

FCHAV {printf ("}\n");}FCHAV {printf ("}\n");}

;;

ListCmdsListCmds : :

| | ListCmds ComandoListCmds Comando

;;

Comando Comando : : CmdCompCmdComp

| | CmdAtribCmdAtrib

;;

CmdAtrib CmdAtrib : : Variavel ATRIB {printf (“:= Variavel ATRIB {printf (“:= ");} Expressao");} Expressao

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

;;

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

Expressao Expressao : : ExprAux1ExprAux1

| | Expressao OR {printf ("|| ");} Expressao OR {printf ("|| ");} ExprAux1ExprAux1

;;

ExprAux1 ExprAux1 : : ExprAux2ExprAux2

| | ExprAux1 AND {printf ("&& ExprAux1 AND {printf ("&& ");} ExprAux2");} ExprAux2

;;

ExprAux2 ExprAux2 : : ExprAux3ExprAux3

| | NOT {printf ("! ");} ExprAux3NOT {printf ("! ");} ExprAux3

;;

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

ExprAux3 ExprAux3 : : ExprAux4ExprAux4

| | ExprAux4 OPREL {ExprAux4 OPREL {

switch ($2) {switch ($2) {

case LT: printf ("< "); case LT: printf ("< "); break;break;

case LE: printf ("<= "); case LE: printf ("<= "); break;break;

case EQ: printf ("= "); case EQ: printf ("= "); break;break;

case NE: printf ("!= "); case NE: printf ("!= "); break;break;

case GT: printf ("> "); case GT: printf ("> "); break;break;

case GE: printf (">= "); case GE: printf (">= "); break;break;

}}

} ExprAux4} ExprAux4

;;

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

ExprAux4 ExprAux4 : : TermoTermo| | ExprAux4 OPAD { ExprAux4 OPAD {switch ($2) {switch ($2) { case MAIS: printf ("+ "); break;case MAIS: printf ("+ "); break; case MENOS: printf ("- "); break;case MENOS: printf ("- "); break;}}

} Termo} Termo;;

Termo Termo : : FatorFator| | Termo OPMULT {Termo OPMULT {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;}}

} Fator} Fator;;

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

FatorFator : : VariavelVariavel

| | CTINT {printf ("%d ", $1);}CTINT {printf ("%d ", $1);}

| | CTREAL {printf ("%g ", $1);}CTREAL {printf ("%g ", $1);}

| | CTCARAC {printf ("\'%c\' ", $1);}CTCARAC {printf ("\'%c\' ", $1);}

| | VERDADE {printf ("verdade ");}VERDADE {printf ("verdade ");}

| | FALSO {printf ("falso ");}FALSO {printf ("falso ");}

| | NEG {printf ("~ ");} Fator NEG {printf ("~ ");} Fator

| | ABPAR {printf ("( ");} Expressao ABPAR {printf ("( ");} Expressao FPAR FPAR

{printf (") ");}{printf (") ");}

;;

VariavelVariavel : : ID {printf ("%s ", $1);}ID {printf ("%s ", $1);}

;;

%%%%

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

/* Inclusao do analisador lexico *//* Inclusao do analisador lexico */

#include "lex.yy.c"#include "lex.yy.c"

/* InicTabSimb: Inicializa a tabela de simbolos *//* InicTabSimb: Inicializa a tabela de simbolos */

void InicTabSimb () {void InicTabSimb () {

int i;int i;

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

tabsimb[i] = NULL;tabsimb[i] = NULL;

}}

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

/*/*

ProcuraSimb (cadeia): Procura cadeia na tabela ProcuraSimb (cadeia): Procura cadeia na tabela de simbolos;de simbolos;

Caso ela ali esteja, retorna um ponteiro para sua Caso ela ali esteja, retorna um ponteiro para sua celula;celula;

Caso contrario, retorna NULL.Caso contrario, retorna NULL.

*/*/

simbolo ProcuraSimb (char *cadeia) {simbolo ProcuraSimb (char *cadeia) {

simbolo s; int i;simbolo s; int i;

i = hash (cadeia);i = hash (cadeia);

for (s = tabsimb[i]; (s!=NULL) && for (s = tabsimb[i]; (s!=NULL) && strcmp(cadeia, s->cadeia); strcmp(cadeia, s->cadeia);

s = s->prox);s = s->prox);

return s;return s;

}}

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

/*/*

InsereSimb (cadeia, tid, tvar):InsereSimb (cadeia, tid, tvar): Insere Insere cadeiacadeia na tabela de na tabela de

simbolos, com simbolos, com tidtid como tipo de identificador e com como tipo de identificador e com tvartvar comocomo

tipo de variavel; Retorna um ponteiro para a celula tipo de variavel; Retorna um ponteiro para a celula inseridainserida

*/*/

simbolo InsereSimb (char *cadeia, int tid, int tvar) {simbolo InsereSimb (char *cadeia, int tid, int tvar) {

int i; simbolo aux, s;int i; simbolo aux, s;

i = hash (cadeia); aux = tabsimb[i];i = hash (cadeia); aux = tabsimb[i];

s = tabsimb[i] = (simbolo) malloc (sizeof (celsimb));s = tabsimb[i] = (simbolo) malloc (sizeof (celsimb));

s->cadeia = (char*) malloc ((strlen(cadeia)+1) * s->cadeia = (char*) malloc ((strlen(cadeia)+1) * sizeof(char));sizeof(char));

strcpy (s->cadeia, cadeia);strcpy (s->cadeia, cadeia);

s->tid = tid;s->tid = tid; s->tvar = tvar;s->tvar = tvar;

s->inic = FALSE;s->inic = FALSE; s->ref = FALSE;s->ref = FALSE;

s->prox = aux;s->prox = aux; return s;return s;

}}

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

/*/*

hash (cadeia): funcao que determina e retorna a hash (cadeia): funcao que determina e retorna a classeclasse

de cadeia na tabela de simbolos implementada de cadeia na tabela de simbolos implementada por hashingpor hashing

*/*/

int hash (char *cadeia) {int hash (char *cadeia) {

int i, h;int i, h;

for (h = i = 0; cadeia[i]; i++) {h += cadeia[i];}for (h = i = 0; cadeia[i]; i++) {h += cadeia[i];}

h = h % NCLASSHASH;h = h % NCLASSHASH;

return h;return h;

}}

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

/* ImprimeTabSimb: Imprime todo o conteudo da /* ImprimeTabSimb: Imprime todo o conteudo da tabela de simbolos */tabela de simbolos */

void ImprimeTabSimb () {void ImprimeTabSimb () {

int i; simbolo s;int i; simbolo s;

printf ("\n\n TABELA DE SIMBOLOS:\n\n");printf ("\n\n TABELA DE SIMBOLOS:\n\n");

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

if (tabsimb[i]) {if (tabsimb[i]) {

printf ("Classe %d:\n", i);printf ("Classe %d:\n", i);

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

printf (" (%s, %s", s->cadeia, printf (" (%s, %s", s->cadeia, nometipid[s->tid]);nometipid[s->tid]);

if (s->tid == IDVAR)if (s->tid == IDVAR)

printf (", %s, %d, %d", printf (", %s, %d, %d",

nometipvar[s->tvar], s-nometipvar[s->tvar], s->inic, s->ref);>inic, s->ref);

printf(")\n");printf(")\n");

}}

}}

}}

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

/* Mensagens de erros semanticos *//* Mensagens de erros semanticos */

void DeclaracaoRepetida (char *s) {void DeclaracaoRepetida (char *s) {

printf ("\n\n***** Declaracao Repetida: %s *****\n\printf ("\n\n***** Declaracao Repetida: %s *****\n\n", s);n", s);

}}

void NaoDeclarado (char *s) {void NaoDeclarado (char *s) {

printf ("\n\n***** Identificador Nao Declarado: %s printf ("\n\n***** Identificador Nao Declarado: %s *****\n\n", s);*****\n\n", s);

}}

void TipoInadequado (char *s) {void TipoInadequado (char *s) {

printf printf

("\n\n***** Identificador de Tipo Inadequado: %s ("\n\n***** Identificador de Tipo Inadequado: %s *****\n\n", s);*****\n\n", s);

}}

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

b) Arquivo tsimb012013.lb) Arquivo tsimb012013.l

%{%{void comentario (void);void comentario (void);char tratachar (char *);char tratachar (char *);%}%}delimdelim [ \t\n\r][ \t\n\r]wsws {delim}+{delim}+digitodigito [0-9][0-9]letraletra [A-Za-z][A-Za-z]ctintctint {digito}+{digito}+idid {letra}({letra}|{digito})*{letra}({letra}|{digito})*ctrealctreal {digito}+\.{digito}*([Ee][+-]?{digito}+\.{digito}*([Ee][+-]?

{digito}+)?{digito}+)?carac1carac1 \\.|[^\\']\\.|[^\\']ctcaracctcarac '{carac1}''{carac1}'%%%%

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

{ws}{ws} { ;}{ ;}"/*""/*" {comentario ();}{comentario ();}caraccarac {return CARAC;}{return CARAC;}falsofalso {return FALSO;}{return FALSO;}intint {return INT;}{return INT;}logiclogic {return LOGIC;}{return LOGIC;}programa programa {return PROGRAMA;}{return PROGRAMA;}realreal {return REAL;}{return REAL;}varvar {return VAR;} {return VAR;} verdadeverdade {return VERDADE;}{return VERDADE;}{id}{id} {strcpy (yylval.cadeia, yytext); {strcpy (yylval.cadeia, yytext);

return ID;}return ID;}{ctcarac}{ctcarac} {yylval.carac = tratachar (yytext); {yylval.carac = tratachar (yytext);

return CTCARAC;}return CTCARAC;}{ctint}{ctint} {yylval.valint = atoi(yytext); return {yylval.valint = atoi(yytext); return

CTINT;}CTINT;}{ctreal}{ctreal} {yylval.valreal = atof(yytext); return {yylval.valreal = atof(yytext); return

CTREAL;}CTREAL;}

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

"||""||" {return OR;}{return OR;}"&&""&&" {return AND;}{return AND;}"!""!" {return NOT;}{return NOT;}"<""<" {yylval.atr = LT; return OPREL;}{yylval.atr = LT; return OPREL;}"<=""<=" {yylval.atr = LE; return OPREL;}{yylval.atr = LE; return OPREL;}">"">" {yylval.atr = GT; return OPREL;}{yylval.atr = GT; return OPREL;}">="">=" {yylval.atr = GE; return OPREL;}{yylval.atr = GE; return OPREL;}"=""=" {yylval.atr = EQ; return OPREL;}{yylval.atr = EQ; return OPREL;}"!=""!=" {yylval.atr = NE; return OPREL;}{yylval.atr = NE; return OPREL;}"+""+" {yylval.atr = MAIS; return OPAD;}{yylval.atr = MAIS; return OPAD;}"-""-" {yylval.atr = MENOS; return OPAD;}{yylval.atr = MENOS; return OPAD;}"*""*" {yylval.atr = MULT; return {yylval.atr = MULT; return

OPMULT;}OPMULT;}"/""/" {yylval.atr = DIV; return OPMULT;}{yylval.atr = DIV; return OPMULT;}"%""%" {yylval.atr = RESTO; return {yylval.atr = RESTO; return

OPMULT;}OPMULT;}"~""~" {return NEG;}{return NEG;}

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

"(""(" {return ABPAR;}{return ABPAR;}")"")" {return FPAR;}{return FPAR;}"{""{" {return ABCHAV;}{return ABCHAV;}"}""}" {return FCHAV;}{return FCHAV;}";"";" {return PVIRG;}{return PVIRG;}",""," {return VIRG;}{return VIRG;}““:=":=" {return ATRIB;}{return ATRIB;}.. {yylval.carac = yytext[0]; return {yylval.carac = yytext[0]; return

INVAL;}INVAL;}%%%%

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

/*/* comentario: le e descarta os comentarios do programa */comentario: le e descarta os comentarios do programa */

void comentario () {void comentario () {

char c; int estado;char c; int estado;

estado = 1;estado = 1;

while (estado != 3) {while (estado != 3) {

switch (estado) {switch (estado) {

case 1:case 1:

c = input ();c = input ();

if (c == EOF) estado = 3;if (c == EOF) estado = 3;

else if (c == '*') estado = 2; break;else if (c == '*') estado = 2; break;

case 2:case 2:

c = input ();c = input ();

if (c == EOF || c == '/') estado = 3;if (c == EOF || c == '/') estado = 3;

else if (c != '*') estado = 1; break;else if (c != '*') estado = 1; break;

}}

}}

}}

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

/*/*tratachar: retorna o codigo ASCII de uma constante tratachar: retorna o codigo ASCII de uma constante do tipo char, eliminando os apostrofos (') e as barras do tipo char, eliminando os apostrofos (') e as barras invertidas (\)invertidas (\)

*/*/

char tratachar (char *s) {char tratachar (char *s) {if (s[1] != '\\') return s[1];if (s[1] != '\\') return s[1];else switch (s[2]) {else switch (s[2]) {

case 'a': case 'a': return 7;return 7; case '\\': case '\\': return 92;return 92;case 'b': case 'b': return 8;return 8; case 'r': case 'r': return 13;return 13;case '\"': case '\"': return 34;return 34; case 'f': case 'f': return 12;return 12;case 't': case 't': return 9;return 9; case 'n': case 'n': return 10;return 10;case '0': case '0': return 0;return 0; case '\'': case '\'': return 39;return 39;case 'v': case 'v': return 11;return 11;default:default: return s[2];return s[2];

}}}}

0 1 2 3 4

' K ' \0

' n '\ \0

' K '\ \0

S =

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

c) Arquivo tsimb012013.datc) Arquivo tsimb012013.dat

programa teste;programa teste;

varvarint i, jjj, h, tb;int i, jjj, h, tb;logic n, m;logic n, m;real v, i;real v, i;carac x, y, z, w;carac x, y, z, w;

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

{{

x := n && m; v := 3.5 * v; y := '@';x := n && m; v := 3.5 * v; y := '@';

{{

i := jjj*falso; jjj := 0;i := jjj*falso; jjj := 0;

}}

jjj := n + 1; i := i + 1;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;

}}

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

m := v + 2 > x; m := v + 2 > x;

m := n != verdade;m := n != verdade;

m := i >= n; m := i >= n;

n := m = 4;n := m = 4;

i := i + 1; i := i + 1;

n := ~ m;n := ~ m;

n := (!m && n) && (m && !n);n := (!m && n) && (m && !n);

i := n / 5; i := n / 5;

i := (!m && n) / 5;i := (!m && n) / 5;

n := (!m || n) && (m || !n);n := (!m || n) && (m || !n);

n := (!m || n) && (tb + v);n := (!m || n) && (tb + v);

n := (!m || n) || (tb + v);n := (!m || n) || (tb + v);

n := (~h + v) * (tb - jjj);n := (~h + v) * (tb - jjj);

i := (!m || n) - 5;i := (!m || n) - 5;

}}

Rodar tudo com o arquivo tsimb012013.dat

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

Exercício 3.1: Inserir no programa 3.1Exercício 3.1: Inserir no programa 3.1 programação para programação para montar a tabela dos montar a tabela dos símbolossímbolos dos programas analisados e realizar dos programas analisados e realizar alguns alguns testes semânticostestes semânticos simples, executando simples, executando as seguintes tarefas:as seguintes tarefas:

a)a)Inicializar Inicializar a tabela de símbolos, a tabela de símbolos, anulandoanulando os os ponteiros de todas as suas classes, e ponteiros de todas as suas classes, e imprimirimprimir o o conteúdo da tabela de símbolos (que deve ser conteúdo da tabela de símbolos (que deve ser vazio)vazio)

b)b)InserirInserir o nome do o nome do programa programa na tabela na tabela

c)c)InserirInserir os nomes das os nomes das variáveis declaradasvariáveis declaradas na na tabela, notificando os casos de tabela, notificando os casos de re-declaraçãore-declaração

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

Exercício 3.1: Inserir no programa 3.1Exercício 3.1: Inserir no programa 3.1 programação para programação para montar a tabela dos montar a tabela dos símbolossímbolos dos programas analisados e realizar dos programas analisados e realizar alguns alguns testes semânticostestes semânticos simples, simples, executando as seguintes tarefas:executando as seguintes tarefas:

  

d)d)Verificar se cada Verificar se cada identificador usadoidentificador usado foi foi declaradodeclarado

e)e)Verificar se cada Verificar se cada identificador usado de identificador usado de variávelvariável é do tipo é do tipo IDVARIDVAR

f)f)MarcarMarcar as variáveis as variáveis referenciadasreferenciadas e e inicializadasinicializadas pelo programa e verificar se pelo programa e verificar se todas as variáveis têm essa marcatodas as variáveis têm essa marca

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

a)a) Inicializar Inicializar a tabela de símbolos, a tabela de símbolos, anulandoanulando os os ponteiros de todas as suas classes, e ponteiros de todas as suas classes, e imprimirimprimir o o conteúdo da tabela de símbolos (que deve ser conteúdo da tabela de símbolos (que deve ser vazio)vazio)

Colocar Colocar {InicTabSimb ();} {InicTabSimb ();} no início da no início da 1ª 1ª produçãoprodução

Colocar Colocar {ImprimeTabSimb ();} {ImprimeTabSimb ();} no final da no final da mesma produção mesma produção

Trocar Trocar $2 $2 por por $3 $3 , na mesma produção, na mesma produção

ProgProg : PROGRAMA ID PVIRG : PROGRAMA ID PVIRG

{printf ("programa %s ;\n", $2);} {printf ("programa %s ;\n", $2);} Decls Decls CmdComp CmdComp

;;

Rodar com o arquivo tsimb012013.dat

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

b)b) InserirInserir o nome do o nome do programa programa na tabela na tabela

Na produção Na produção ProgProg, na ação depois de , na ação depois de PVIRGPVIRG, , depois da chamada de depois da chamada de printfprintf, colocar , colocar

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

ProgProg : {- - - -} PROGRAMA ID PVIRG : {- - - -} PROGRAMA ID PVIRG

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

Decls CmdComp {- - - -}Decls CmdComp {- - - -}

;; Rodar com o arquivo tsimb012013.dat

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

c)c) InserirInserir os nomes das os nomes das variáveis declaradasvariáveis declaradas na na tabela, notificando os casos de tabela, notificando os casos de re-declaraçãore-declaração..

Declarar uma nova variável global inteira: Declarar uma nova variável global inteira: tipocorrentetipocorrente

Na produção Na produção ElemDeclElemDecl, na ação depois de , na ação depois de IDID, , depois do depois do printfprintf, colocar, colocar

if (ProcuraSimb ($1) != NULL)if (ProcuraSimb ($1) != NULL)

DeclaracaoRepetida ($1);DeclaracaoRepetida ($1);

elseelse

InsereSimb ($1, IDVAR, InsereSimb ($1, IDVAR, tipocorrente);tipocorrente);

ElemDecl ElemDecl : ID {printf ("%s ", $1); }: ID {printf ("%s ", $1); }

;;

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

Nas produções Nas produções TipoTipo, atribuir valor à variável , atribuir valor à variável tipocorrentetipocorrente

tipocorrente = INTEGER;tipocorrente = FLOAT;tipocorrente = CHARtipocorrente = LOGICAL;

Tipo: INT {printf (- -); | REAL {printf (- -); | CARAC {printf (- -); | LOGIC {printf (- -);

}}} }

Rodar com o arquivo tsimb012013.dat

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

d)d) Verificar se cada Verificar se cada identificador usadoidentificador usado foi foi declaradodeclarado

e)e) Verificar se cada Verificar se cada identificador usado de identificador usado de variávelvariável é do tipo é do tipo IDVARIDVAR

Na produção Na produção VariavelVariavel, , na ação depois de na ação depois de IDID, , depois do depois do printfprintf, colocar, colocar

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);TipoInadequado ($1);

VariavelVariavel : ID {printf ("%s ", $1); }: ID {printf ("%s ", $1); }

;;Rodar com o arquivo tsimb012013.dat

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

f)f) MarcarMarcar as variáveis as variáveis referenciadasreferenciadas e e inicializadasinicializadas pelo programa e verificar se todas pelo programa e verificar se todas as variáveis têm essa marcaas variáveis têm essa marca

Acrescentar o campo Acrescentar o campo simbsimb na declaração na declaração %union%union::

/* Definicao dos campos dos tipos dos atributos *//* Definicao dos campos dos tipos dos atributos */

%union {%union {

char cadeia[50];char cadeia[50];

int atr, valint;int atr, valint;

float valreal;float valreal;

char carac;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

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

Declarar que o não-terminal Declarar que o não-terminal VariavelVariavel tem tem como atributo o campo como atributo o campo simbsimb da da %union%union, , colocando antes dos colocando antes dos tokenstokens::

%type%type <simb><simb> VariavelVariavel

/* Declaracao dos atributos dos tokens e /* Declaracao dos atributos dos tokens e dos nao-terminais */dos nao-terminais */

%token%token <cadeia><cadeia> IDID

%token%token <cadeia><cadeia> CTCARACCTCARAC

%token%token <valint><valint> CTINTCTINT

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

Na produção Na produção Variavel Variavel, no final da ação final, , no final da ação final, colocar:colocar:

$$ = simb;$$ = simb;

VariavelVariavel : ID {: ID {

printf - - - - - printf - - - - -

simb = ProcuraSimb ($1);simb = ProcuraSimb ($1);

if - - - - - if - - - - -

else if - - - - -else if - - - - -

}}

;;

O atributo do não-terminal Variavel é um ponteiro para a célula correspondente a ID na tabsimb

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

Na produção Na produção Fator : Variavel Fator : Variavel, colocar, no , colocar, no final, a ação:final, a ação:

{if ($1 != NULL) $1->ref = TRUE;}{if ($1 != NULL) $1->ref = TRUE;}

FatorFator : : VariavelVariavel

Na produção Na produção CmdAtribCmdAtrib, colocar, depois de , colocar, depois de VariavelVariavel, a ação:, a ação:

{if ($1 != NULL) $1->inic = $1->ref = {if ($1 != NULL) $1->inic = $1->ref = TRUE;}TRUE;}

CmdAtrib CmdAtrib : Variavel ATRIB {printf (“<- : Variavel ATRIB {printf (“<- ");} ");} Expressao PVIRG {printf (";\ Expressao PVIRG {printf (";\n");}n");}

Rodar com o arquivo tsimb012013.dat

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

Fazer uma função Fazer uma função VerificaInicRefVerificaInicRef, que , que percorra toda a percorra toda a tabsimbtabsimb, checando e , checando e avisando os casos de identificadores não-avisando os casos de identificadores não-inicializados e não-referenciadosinicializados e não-referenciados

– Não esquecer o Não esquecer o protótipoprotótipo

Chamar Chamar VerificaInicRefVerificaInicRef antes de antes de ImprimeTabSimbImprimeTabSimb, na ação final da produção , na ação final da produção ProgProg Rodar com o

arquivo tsimb012013.dat

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

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

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

Numa produção contendo um Numa produção contendo um operadoroperador de de expressões, os expressões, os operandosoperandos são são não-terminaisnão-terminais

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

Termo Termo : Termo : Termo OPMULT OPMULT FatorFator

No lado direito, No lado direito, TermoTermo e e FatorFator representam representam os operandos de os operandos de OPMULTOPMULT

É conveniente que esses É conveniente que esses não-terminaisnão-terminais e e todos aqueles relacionados com todos aqueles relacionados com expressõesexpressões tenham, como tenham, como atributoatributo o o tipotipo da sub- da sub-expressão que eles representamexpressão que eles representam

  

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

Acrescentar o campo Acrescentar o campo tipoexprtipoexpr na declaração na declaração %union%union::

  

%union {%union {

char cadeia[50];char cadeia[50]; int atr, valint;int atr, valint;

float valreal;float valreal; char carac;char carac; simbolo simb; simbolo simb;

int tipoexpr;int tipoexpr;

}}

   Declarar que todos os não-terminais relacionados Declarar que todos os não-terminais relacionados

com com expressões expressões têm como atributo o campo têm como atributo o campo tipoexprtipoexpr::

  

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

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

Em cada produção relacionada com Em cada produção relacionada com expressõesexpressões, deve ser calculado o atributo do , deve ser calculado o atributo do lado esquerdo (lado esquerdo ($$$$))

Nas produções contendo Nas produções contendo operadoresoperadores, devem , devem ser feitos testes de ser feitos testes de compatibilidadecompatibilidade

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

Exemplo: Exemplo: Teste de compatibilidade do operador Teste de compatibilidade do operador NEGNEG

No não terminal No não terminal VariavelVariavel, já está calculado o , já está calculado o valor de valor de $$$$::

VariavelVariavel : ID {: ID {

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

simb = ProcuraSimb ($1);simb = ProcuraSimb ($1);

if (simb == NULL) NaoDeclarado if (simb == NULL) NaoDeclarado ($1);($1);

else if (simb->tid != IDVAR) else if (simb->tid != IDVAR)

TipoInadequado ($1);TipoInadequado ($1);

$$ = simb;$$ = simb;

}}

;;

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

Calcular o valor de Calcular o valor de $$$$ em todas as produções de em todas as produções de FatorFator e fazer teste de compatibilidade nas e fazer teste de compatibilidade nas produções cabíveis:produções cabíveis:

FatorFator : Variavel {: Variavel {

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

$1->ref = TRUE; $1->ref = TRUE;

$$ = $1->tvar;$$ = $1->tvar;

}}

}}

| CTINT {printf ("%d ", $1); | CTINT {printf ("%d ", $1); $$ = INTEGER; $$ = INTEGER; }}

| CTREAL {printf ("%g ", $1); | CTREAL {printf ("%g ", $1); $$ = FLOAT;$$ = FLOAT; }}

| CTCARAC {printf ("%c ", $1); | CTCARAC {printf ("%c ", $1); $$ = CHAR;$$ = CHAR; }}

| VERDADE {printf (“verdade "); | VERDADE {printf (“verdade "); $$ = $$ = LOGICAL;LOGICAL; }}

| FALSO {printf ("falso "); | FALSO {printf ("falso "); $$ = LOGICAL;$$ = LOGICAL; }}

Trocar o conteúdo da ação por

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

Calcular o valor de Calcular o valor de $$$$ em todas as produções de em todas as produções de FatorFator e fazer teste de compatibilidade nas e fazer teste de compatibilidade nas produções cabíveis:produções cabíveis:

FatorFator : NEG {printf ("~ ");} Fator : NEG {printf ("~ ");} Fator

{{

if ($3 != INTEGER &&if ($3 != INTEGER &&

$3 != FLOAT && $3 != CHAR)$3 != FLOAT && $3 != CHAR)

Incompatibilidade ("Operando improprio para Incompatibilidade ("Operando improprio para menos unario");menos unario");

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

else $$ = INTEGER;else $$ = INTEGER;

}}

| ABPAR {printf ("\( ");} Expressao FPAR | ABPAR {printf ("\( ");} Expressao FPAR

{ printf (") "); { printf (") "); $$ = $3; $$ = $3; }}

;;

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

Criar a função Criar a função Incompatibilidade Incompatibilidade e seu e seu protótipo:protótipo:

void Incompatibilidade (char *);void Incompatibilidade (char *);

void Incompatibilidade (char *s) {void Incompatibilidade (char *s) {

printf ("\n\n***** Incompatibilidade: %s printf ("\n\n***** Incompatibilidade: %s *****\n\n", s);*****\n\n", s);

}} Rodar com o arquivo tsimb012013.dat

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

Exemplo: Exemplo: Teste de compatibilidade do operador Teste de compatibilidade do operador OPMULTOPMULT

Calcular o valor de Calcular o valor de $$$$ em todas as produções em todas as produções do não-terminal do não-terminal TermoTermo e fazer teste de e fazer teste de compatibilidade nas produções cabíveiscompatibilidade nas produções cabíveis

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

Termo : Fator Termo : Fator /* Default: $$ = $1; *//* Default: $$ = $1; */| Termo OPMULT {- - - - -} Fator | Termo OPMULT {- - - - -} Fator {switch ($2) {{switch ($2) { case MULT: case DIV:case MULT: case DIV: if ($1 != INTEGER && $1 != FLOAT && $1 != if ($1 != INTEGER && $1 != FLOAT && $1 !=

CHARCHAR || $4 != INTEGER && $4!=FLOAT && $4!|| $4 != INTEGER && $4!=FLOAT && $4!

=CHAR)=CHAR) IncompatibilidadeIncompatibilidade

("Operando improprio para operador ("Operando improprio para operador aritmetico");aritmetico");

if ($1 == FLOAT || $4 == FLOAT) $$ = FLOAT;if ($1 == FLOAT || $4 == FLOAT) $$ = FLOAT; else $$ = INTEGER; else $$ = INTEGER; break;break; case RESTO:case RESTO: if ($1 != INTEGER && $1 != CHAR if ($1 != INTEGER && $1 != CHAR || $4 != INTEGER && $4 != CHAR)|| $4 != INTEGER && $4 != CHAR) IncompatibilidadeIncompatibilidade

("Operando improprio para operador resto");("Operando improprio para operador resto"); $$ = INTEGER; $$ = INTEGER; break;break; } } } } ;;

Exercício: fazer testes para os operadores OPAD, OPREL, NOT, AND e OR

Rodar com o arquivo tsimb012013.dat

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

Programa 3.2: Gramática sem Programa 3.2: Gramática sem subprogramas, com variáveis escalares e subprogramas, com variáveis escalares e indexadas, comandos de atribuição, se, indexadas, comandos de atribuição, se, enquanto, ler e escreverenquanto, ler e escrever

Para os exercícios 3.3, 3.4 e 3.5, considerar os Para os exercícios 3.3, 3.4 e 3.5, considerar os arquivos arquivos tsimb022013.l tsimb022013.l ee tsimb022013.y tsimb022013.y da da aba de aba de ‘Códigos’‘Códigos’ da página do professor da página do professor

Rodar esses programas com o arquivo de Rodar esses programas com o arquivo de dados dados tsimb012013.dattsimb012013.dat

Esses programas já fazem teste de Esses programas já fazem teste de compatibilidade de compatibilidade de expressõesexpressões

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

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

  

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

CmdAtrib:CmdAtrib: Variavel {Variavel {

if ($1 != NULL) $1->inic = $1->ref = TRUE;if ($1 != NULL) $1->inic = $1->ref = TRUE;

} ATRIB {printf (":= ");} Expressao PVIRG {} ATRIB {printf (":= ");} Expressao PVIRG {

printf (";\n");printf (";\n");

if ($1 != NULL)if ($1 != NULL)

if ((($1->tvar == INTEGER || $1->tvar == if ((($1->tvar == INTEGER || $1->tvar == CHAR) && CHAR) &&

($5 == FLOAT || $5 == LOGICAL)) ||($5 == FLOAT || $5 == LOGICAL)) ||

($1->tvar == FLOAT && $5 == ($1->tvar == FLOAT && $5 == LOGICAL) ||LOGICAL) ||

($1->tvar == LOGICAL && $5 != ($1->tvar == LOGICAL && $5 != LOGICAL))LOGICAL))

Incompatibilidade Incompatibilidade

("Lado direito de comando de atribuicao ("Lado direito de comando de atribuicao improprio");improprio");

}}

;; Testar com o arquivo de dados Testar com o arquivo de dados tsimb012013.dattsimb012013.dat

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

Exercício 3.4: Exercício 3.4: Inserir na gramática do Inserir na gramática do programa programa 3.23.2 testes semânticos para as produções dos testes semânticos para as produções dos comandos comandos sese, , enquantoenquanto, , lerler, , escreverescrever que que aparecem na linguagem COMP-ITA 2013aparecem na linguagem COMP-ITA 2013

Produções:Produções:

Comando Comando : CmdComp | CmdSe | CmdEnquanto | : CmdComp | CmdSe | CmdEnquanto | CmdLer CmdLer

| CmdEscrever | CmdAtrib| CmdEscrever | CmdAtrib

CmdSeCmdSe : : sese (( Expressao Expressao )) Comando CmdSenao Comando CmdSenao

CmdSenaoCmdSenao : : ε ε | | senaosenao Comando Comando

CmdEnquantoCmdEnquanto : : enquanto ( enquanto ( Expressao Expressao ) ) ComandoComando

CmdLerCmdLer: : lerler ( ( ListVar ListVar )) ;;

ListVarListVar : Variavel | ListVar : Variavel | ListVar , , Variavel Variavel

CmdEscreverCmdEscrever : : escreverescrever ( ( ListEscr ListEscr )) ;;

ListEscrListEscr : ElemEscr | ListEscr : ElemEscr | ListEscr ,, ElemEscr ElemEscr

ElemEscrElemEscr : : CADEIACADEIA | Expressao | Expressao

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

Comando Comando : CmdComp | CmdSe | CmdEnquanto | CmdLer : CmdComp | CmdSe | CmdEnquanto | CmdLer

| CmdEscrever | CmdAtrib| CmdEscrever | CmdAtrib

CmdSeCmdSe : : sese (( Expressao Expressao )) Comando CmdSenao Comando CmdSenao

CmdSenaoCmdSenao : : ε ε | | senaosenao Comando Comando

CmdEnquantoCmdEnquanto : : enquanto ( enquanto ( Expressao Expressao ) ) ComandoComando

CmdLerCmdLer : : lerler ( ( ListVar ListVar )) ;;

ListVarListVar : Variavel | ListVar : Variavel | ListVar , , Variavel Variavel

CmdEscreverCmdEscrever : : escreverescrever ( ( ListEscr ListEscr )) ;;

ListEscrListEscr : ElemEscr | ListEscr : ElemEscr | ListEscr ,, ElemEscr ElemEscr

ElemEscrElemEscr: : CADEIACADEIA | Expressao | Expressao

Marcar as Marcar as variáveis lidasvariáveis lidas como como inicializadasinicializadas e e referenciadas referenciadas (tal como no lado esquerdo de (tal como no lado esquerdo de atribuição)atribuição)

Verificar se as Verificar se as expressõesexpressões dos comandos dos comandos sese e e enquantoenquanto são são lógicaslógicas

Testar o programa com o arquivo de dados Testar o programa com o arquivo de dados tsimb022013.dattsimb022013.dat

Abrir o arquivo tsimb022013.dat

As variáveis n e num são lidas (inic e ref)

Expressões inteiras em comandos se e enquanto

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

Exercício 3.5: Exercício 3.5: Inserir na gramática do Inserir na gramática do programa 3.2programa 3.2 alterações na alterações na tabela de símbolostabela de símbolos e e testes testes semânticossemânticos para as produções que aparecem na para as produções que aparecem na linguagem COMP-ITA 2013, envolvendo linguagem COMP-ITA 2013, envolvendo variáveis variáveis indexadasindexadas

Produções:Produções:

ElemDeclElemDecl :: IDID | | ID [ID [ ListDim ListDim ]]

ListDimsListDims :: CTINT | CTINT | ListDim ListDim , CTINT, CTINT

VariavelVariavel : : IDID | | IDID [[ ListSubscr ListSubscr ]]

ListSubscrListSubscr : : ExprAux4ExprAux4 | ListSubscr | ListSubscr ,, ExprAux4 ExprAux4

Observar estas produções no arquivo Observar estas produções no arquivo tsimb022013.ytsimb022013.y

Testar o programa com o arquivo de dados Testar o programa com o arquivo de dados tsimb032013.dattsimb032013.dat

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

Preparar a Preparar a tabela de símbolostabela de símbolos para guardar para guardar informações sobre: informações sobre:

Número de dimensõesNúmero de dimensões de uma variável de uma variável indexadaindexada

Número de elementosNúmero de elementos de cada dimensão de cada dimensão TipoTipo de cada elemento de cada elemento

Exemplo:Exemplo: para a declaração para a declaração

int A[10, 20, 5]int A[10, 20, 5]: :

A

cadeia

IDVAR

tid

INTEGER

tvar

0

inic

0

ref

1

array

3

ndims

10

20

5 ..........

dims

0 1 2 3 10

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

/* Definicao de outras constantes *//* Definicao de outras constantes */

#define#define NCLASSHASHNCLASSHASH 2323

#define#define TRUETRUE 11

#define#define FALSEFALSE 00

#define #define MAXDIMSMAXDIMS 1010

/* Declaracoes para a tabela de simbolos *//* Declaracoes para a tabela de simbolos */

typedef struct celsimb celsimb; typedef celsimb typedef struct celsimb celsimb; typedef celsimb *simbolo;*simbolo;

struct celsimb {struct celsimb {

char *cadeia; int tid, tvar char *cadeia; int tid, tvar , ndims, , ndims, dims[MAXDIMS+1]dims[MAXDIMS+1] ;;

char inic, ref char inic, ref , array , array ; simbolo prox; ; simbolo prox;

};};A

cadeia

IDVAR

tid

INTEGER

tvar

0

inic

0

ref

1

array

3

ndims

10

20

5 ..........

dims

0 1 2 3 10

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

/* ImprimeTabSimb: Imprime todo o conteudo da tabela de simbolos *//* ImprimeTabSimb: Imprime todo o conteudo da tabela de simbolos */void ImprimeTabSimb () {void ImprimeTabSimb () {

int i; simbolo s;int i; simbolo s;printf ("\n\n TABELA DE SIMBOLOS:\n\n");printf ("\n\n TABELA DE SIMBOLOS:\n\n");for (i = 0; i < NCLASSHASH; i++)for (i = 0; i < NCLASSHASH; i++)

if (tabsimb[i]) {if (tabsimb[i]) {printf ("Classe %d:\n", i);printf ("Classe %d:\n", i);for (s = tabsimb[i]; s!=NULL; s = s->prox){for (s = tabsimb[i]; s!=NULL; s = s->prox){

printf (- - - - -);printf (- - - - -);if (s->tid == IDVAR) if (s->tid == IDVAR) {{

printf (- - - - -);printf (- - - - -);if (s->array == TRUE) { int j;if (s->array == TRUE) { int j;

printf (", EH ARRAY\n\tndims = %d, dimensoes:", s-printf (", EH ARRAY\n\tndims = %d, dimensoes:", s->ndims);>ndims);

for (j = 1; j <= s->ndims; j++)for (j = 1; j <= s->ndims; j++) printf (" %d", s-printf (" %d", s-

>dims[j]);>dims[j]);}}

}}printf(")\n");printf(")\n");

}}}}

}}

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

Alterar toda programação da montagem da Alterar toda programação da montagem da tabela de símbolostabela de símbolos e de e de testes semânticostestes semânticos realizados até agorarealizados até agora

A

cadeia

IDVAR

tid

INTEGER

tvar

0

inic

0

ref

1

array

3

ndims

10

20

5 ..........

dims

0 1 2 3 10

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

Nas declarações das variáveis:Nas declarações das variáveis:

ElemDecl : ID {printf ("%s ", $1);ElemDecl : ID {printf ("%s ", $1);

if (ProcuraSimb ($1) != NULL) if (ProcuraSimb ($1) != NULL) DeclaracaoRepetida ($1);DeclaracaoRepetida ($1);

else else { simb = { simb = InsereSimb ($1, IDVAR, InsereSimb ($1, IDVAR, tipocorrente);tipocorrente);

simb->array = FALSE; }simb->array = FALSE; }

}}

| | ID ABCOL {printf ("%s [ ", $1);ID ABCOL {printf ("%s [ ", $1);

if (ProcuraSimb ($1) != NULL) if (ProcuraSimb ($1) != NULL) DeclaracaoRepetida ($1);DeclaracaoRepetida ($1);

else else { simb = { simb = InsereSimb ($1, IDVAR, InsereSimb ($1, IDVAR, tipocorrente);tipocorrente);

simb->array = TRUE; simb->ndims = 0;}simb->array = TRUE; simb->ndims = 0;}

} ListDim FCOL {printf ("] ");}} ListDim FCOL {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

10

20

5 ..........

dims

0 1 2 3 10

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

No dimensionamento das variáveis indexadas, No dimensionamento das variáveis indexadas, inclusive verificando se a inclusive verificando se a constante inteiraconstante inteira usada no usada no dimensionamentodimensionamento de uma variável de uma variável indexada é indexada é positivapositiva: :

ListDim : CTINT { printf ("%d ", $1);ListDim : CTINT { printf ("%d ", $1);

if ($1 <= 0) Esperado ("Valor inteiro if ($1 <= 0) Esperado ("Valor inteiro positivo");positivo");

simb->ndims++; simb->dims[simb->ndims] simb->ndims++; simb->dims[simb->ndims] = $1;= $1;

}}

| ListDim VIRG CTINT { printf (", %d ", $3);| ListDim VIRG CTINT { printf (", %d ", $3);

if ($3 <= 0) Esperado ("Valor inteiro if ($3 <= 0) Esperado ("Valor inteiro positivo");positivo");

simb->ndims++; simb->dims[simb->ndims] simb->ndims++; simb->dims[simb->ndims] = $3;= $3;

}}

;;

A

cadeia

IDVAR

tid

INTEGER

tvar

0

inic

0

ref

1

array

3

ndims

10

20

5 ..........

dims

0 1 2 3 10

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

Criar o protótipo:Criar o protótipo:

void Esperado (char *);void Esperado (char *);

E a função:E a função:

void Esperado (char *s) {void Esperado (char *s) {

printf ("\n\n***** Esperado: %s *****\n\printf ("\n\n***** Esperado: %s *****\n\n", s);n", s);

}}

Rodar o programa com o arquivo Rodar o programa com o arquivo tsimb032013.dattsimb032013.dat, para verificar se as , para verificar se as informações foram introduzidas na informações foram introduzidas na tabsimbtabsimb

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

Na segunda produção do não-terminal Na segunda produção do não-terminal VariavelVariavel, , para se determinar o para se determinar o atributoatributo do lado esquerdo, do lado esquerdo, foi usada a seguinte programação:foi usada a seguinte programação:

Variavel : ID { - - - - - $$ = simb; }Variavel : ID { - - - - - $$ = simb; }

| ID ABCOL {| ID ABCOL {

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;$<simb>$ = simb;

} ListSubscr FCOL { printf ("] "); } ListSubscr FCOL { printf ("] "); $$ = $<simb>3;$$ = $<simb>3; }}

;;

É a especificação do É a especificação do atributoatributo de um de um não-não-terminal fictícioterminal fictício

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

Por default, o Por default, o atributoatributo de um de um não-terminal não-terminal fictício fictício também é do tipo também é do tipo inteirointeiro

Muitas vezes é Muitas vezes é desejáveldesejável especificar para ele um especificar para ele um dos campos da dos campos da %union%union

Isso não pode ser feito por uma declaração Isso não pode ser feito por uma declaração %type%type

%type %type só declara atributos de não-terminais só declara atributos de não-terminais não-fictíciosnão-fictícios

Para tanto, coloca-se o campo escolhido entre os Para tanto, coloca-se o campo escolhido entre os caracteres caracteres ‘<’‘<’ e e ‘>’‘>’, tudo isso logo após o , tudo isso logo após o primeiro caractere primeiro caractere ‘$’‘$’, por exemplo, , por exemplo, $<cadeia>$$<cadeia>$, , $<simb>1$<simb>1, , $<valint>2$<valint>2

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

Exemplo: Exemplo: Seja a seguinte produção:Seja a seguinte produção:

A A : : B {simb = InsereSimb (- - -);} C {$$ = simb-B {simb = InsereSimb (- - -);} C {$$ = simb->tvar;}>tvar;}

Onde Onde simbsimb é uma variável global e é uma variável global e

%union {int tipoexpr; simbolo simb;}%union {int tipoexpr; simbolo simb;}

%type <tipoexpr> A%type <tipoexpr> A

Por essa programação, deseja-se que o atributo de Por essa programação, deseja-se que o atributo de AA seja o seja o tipo da variável tipo da variável da célula apontada por da célula apontada por simbsimb

Mas, no processamento do não-terminal Mas, no processamento do não-terminal CC, pode ser , pode ser que o valor de que o valor de simbsimb seja alterado, não se realizando seja alterado, não se realizando o desejado o desejado

Então a programação na produção deve mudar paraEntão a programação na produção deve mudar para

A A : : B {$<simb>$ = InsereSimb (- - -);} C {$$ = B {$<simb>$ = InsereSimb (- - -);} C {$$ = $<simb>2->tvar;}$<simb>2->tvar;}

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

Realizar ainda os seguintes testes semânticos:Realizar ainda os seguintes testes semânticos:

Verificar se as Verificar se as expressõesexpressões que aparecem nos que aparecem nos subscritossubscritos das variáveis indexadas são do tipo das variáveis indexadas são do tipo inteirointeiro ou ou caracterecaractere

Verificar se uma variável de Verificar se uma variável de tipo escalartipo escalar tem tem subscritossubscritos e se uma e se uma indexadaindexada não tem não tem subscritossubscritos

Verificar se o Verificar se o número de subscritosnúmero de subscritos de uma de uma variável indexada é igual ao seu variável indexada é igual ao seu número de número de dimensõesdimensões declarado declarado

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

Verificar se as Verificar se as expressõesexpressões que aparecem nos que aparecem nos subscritossubscritos das variáveis indexadas são do tipo das variáveis indexadas são do tipo inteirointeiro ou ou caracterecaractere

Produções para este teste:Produções para este teste:

ListSubscr: ExprAux4 ListSubscr: ExprAux4

{{

if ($1 != INTEGER && $1 != CHAR)if ($1 != INTEGER && $1 != CHAR)

Incompatibilidade ("Tipo inadequado para Incompatibilidade ("Tipo inadequado para subscrito");subscrito");

}}

| ListSubscr VIRG {printf (", ");} ExprAux4 | ListSubscr VIRG {printf (", ");} ExprAux4

{{

if ($4 != INTEGER && $4 != CHAR)if ($4 != INTEGER && $4 != CHAR)

Incompatibilidade ("Tipo inadequado para Incompatibilidade ("Tipo inadequado para subscrito");subscrito");

}}

;;

Rodar o programa com o arquivo tsimb032013.dat

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

Verificar se uma variável de Verificar se uma variável de tipo escalartipo escalar tem tem subscritossubscritos e se uma e se uma indexadaindexada não tem não tem subscritossubscritos

Verificar se o Verificar se o número de subscritosnúmero de subscritos de uma de uma variável indexada é igual ao seu variável indexada é igual ao seu número de número de dimensões dimensões declaradodeclarado

Deve-se obter o Deve-se obter o número de subscritosnúmero de subscritos que que aparecem depois do nome de uma aparecem depois do nome de uma variávelvariável

Em seguida, deve-se Em seguida, deve-se compararcomparar esse número esse número com o com o número de dimensõesnúmero de dimensões desse nome na desse nome na tabela de símbolostabela de símbolos

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

O não-terminal O não-terminal ListSubscrListSubscr terá como atributo terá como atributo o número de subscritos:o número de subscritos:

%union {%union {

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

char carac; simbolo simb; char carac; simbolo simb;

int tipoexpr; int tipoexpr; int nsubscr;int nsubscr;

}}

%type <tipoexpr> Expressao ExprAux1 %type <tipoexpr> Expressao ExprAux1 ExprAux2ExprAux2

ExprAux3 ExprAux4 ExprAux3 ExprAux4 Termo FatorTermo Fator

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

%type <nsubscr> ListSubscr%type <nsubscr> ListSubscr

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

Nas produções de Nas produções de ListSubscrListSubscr::

ListSubscr: ExprAux4 {ListSubscr: ExprAux4 {

if ($1 != INTEGER && $1 != CHAR)if ($1 != INTEGER && $1 != CHAR)

Incompatibilidade ("Tipo inadequado Incompatibilidade ("Tipo inadequado para subscrito");para subscrito");

$$ = 1;$$ = 1;

}}

|| ListSubscr VIRG {printf (", ");} ExprAux4 {ListSubscr VIRG {printf (", ");} ExprAux4 {

if ($4 != INTEGER && $4 != CHAR)if ($4 != INTEGER && $4 != CHAR)

Incompatibilidade ("Tipo inadequado Incompatibilidade ("Tipo inadequado para subscrito");para subscrito");

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

}}

;;

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

Nas produções de Nas produções de VariavelVariavel::

Variavel: ID { - - - - - $$ = simb;Variavel: ID { - - - - - $$ = simb;

if ($$ != NULL)if ($$ != NULL)

if ($$->array == TRUE)if ($$->array == TRUE)

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

}}

|| ID ABCOL { - - - - - $<simb>$ = simb; } ListSubscr FCOL {ID ABCOL { - - - - - $<simb>$ = simb; } ListSubscr FCOL {

printf ("] "); $$ = $<simb>3;printf ("] "); $$ = $<simb>3;

if ($$ != NULL)if ($$ != NULL)

if ($$->array == FALSE)if ($$->array == FALSE)

NaoEsperado ("Subscrito\(s)");NaoEsperado ("Subscrito\(s)");

else if ($$->ndims != $4)else if ($$->ndims != $4)

Incompatibilidade Incompatibilidade

("Numero de subscritos incompativel com ("Numero de subscritos incompativel com declaracao");declaracao");

}}

;;

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

Criar o protótipo:Criar o protótipo:

void NaoEsperado (char *);void NaoEsperado (char *);

E a função:E a função:

void NaoEsperado (char *s) {void NaoEsperado (char *s) {

printf ("\n\n***** Nao Esperado: %s *****\n\printf ("\n\n***** Nao Esperado: %s *****\n\n", s);n", s);

}}Rodar o programa com o arquivo tsimb032013.dat