CES-41 COMPILADORES

Post on 12-Jan-2016

38 views 0 download

description

CES-41 COMPILADORES. Capítulo III Diagramas de Transições. Capítulo III – Diagramas de Transições. 3.1 – Considerações iniciais 3.2 – Uma linguagem ilustrativa: Mini-Pascal 3.3 – Análise léxica por diagramas de transições 3.4 – Análise sintática por diagramas de transições - PowerPoint PPT Presentation

Transcript of CES-41 COMPILADORES

CES-41 CES-41 COMPILADORESCOMPILADORES

Capítulo IIICapítulo III

Diagramas de Diagramas de TransiçõesTransições

Capítulo III – Capítulo III – Diagramas de Diagramas de

TransiçõesTransições3.1 – Considerações iniciais3.1 – Considerações iniciais

3.2 – Uma linguagem ilustrativa: Mini-Pascal3.2 – Uma linguagem ilustrativa: Mini-Pascal

3.3 – Análise léxica por diagramas de 3.3 – Análise léxica por diagramas de transiçõestransições

3.4 – Análise sintática por diagramas de 3.4 – Análise sintática por diagramas de transiçõestransições

3.5 – Tabela de símbolos em diagramas de 3.5 – Tabela de símbolos em diagramas de transiçõestransições

3.6 – Testes semânticos em diagramas de 3.6 – Testes semânticos em diagramas de transiçõestransições

3.7 – Geração de código intermediário3.7 – Geração de código intermediário

3.1 – Considerações 3.1 – Considerações IniciaisIniciais

Diagramas de transições:Diagramas de transições: usados na construção usados na construção do do front-endfront-end de um compilador de um compilador

Forma Forma didáticadidática de concepção de um de concepção de um front-endfront-end

Há outros métodos Há outros métodos mais eficientesmais eficientes, porém menos , porém menos didáticosdidáticos

A seguir, análises léxica, sintática e semântica e A seguir, análises léxica, sintática e semântica e geração de código intermediário por diagramas de geração de código intermediário por diagramas de transiçõestransições

Diagrama de Diagrama de transições léxicastransições léxicas é um é um autômato autômato finito determinísticofinito determinístico

Exemplo: Exemplo: Diagrama de transições para Diagrama de transições para reconhecer reconhecer constantes numéricasconstantes numéricas em em FortranFortran

d é um dígito genéri

co

Arcos de qualquer vértice para o vértice Arcos de qualquer vértice para o vértice ErroErro não são mostrados, mas não são mostrados, mas existemexistem

d é um dígito genéri

co

d é um dígito genéri

co

Estado não final

Estado final

São reconhecidas constantes como: São reconhecidas constantes como: 1313, , +13+13, , --1313, , 13.13., , 1.251.25, , .25.25, , -.25-.25, , -32.43-32.43, , 13E-1513E-15, , 13.E-1513.E-15, , -13.25E+72-13.25E+72, , .75E5.75E5

d é um dígito genéri

co

Para as transições sintáticas usam-se Para as transições sintáticas usam-se vários vários diagramas de transiçõesdiagramas de transições; um para cada não-; um para cada não-terminalterminal

Existem linguagens para as quais é Existem linguagens para as quais é difícil ou difícil ou até impossívelaté impossível a utilização de diagramas de a utilização de diagramas de transições transições sintáticassintáticas

Para ilustrarPara ilustrar será utilizada a linguagem será utilizada a linguagem Mini-Mini-PascalPascal extraída de extraída de PascalPascal, apresentada logo a , apresentada logo a seguirseguir

3.2 – Uma linguagem 3.2 – Uma linguagem ilustrativa: Mini-Pascalilustrativa: Mini-Pascal

3.2.1 – Gramática do Mini-Pascal3.2.1 – Gramática do Mini-Pascal

A gramática do Mini-Pascal não é A gramática do Mini-Pascal não é recursiva à recursiva à esquerdaesquerda, mas apresenta a , mas apresenta a ambiguidade dos ambiguidade dos comandos condicionaiscomandos condicionais

Não tem Não tem subprogramassubprogramas, nem , nem variáveis indexadasvariáveis indexadas e seu único comando repetitivo é o e seu único comando repetitivo é o whilewhile

Não-terminais Não-terminais estão emestão em itálicoitálico

Terminais Terminais são átomos obtidos dosão átomos obtidos do analisador analisador léxicoléxico;; são apresentados comsão apresentados com LETRAS LETRAS MAIÚSCULASMAIÚSCULAS, ou, ou com os com os caracterescaracteres que os que os identificamidentificam

Produções da gramática:Produções da gramática:

Prog Prog PROGRAM IDPROGRAM ID ;; Decls CmdCompDecls CmdComp ..

Decls Decls εε VARVAR ListDeclListDecl

ListDecl ListDecl DeclTip DeclTip DeclTip ListDeclDeclTip ListDecl

DeclTip DeclTip ListIdListId :: TipTip ;;

ListId ListId IDID IDID ,, ListIdListId

Tip Tip INTEGERINTEGER BOOLEANBOOLEAN

CmdComp CmdComp BEGINBEGIN ListCmd ListCmd ENDEND

ListCmd ListCmd Cmd Cmd Cmd Cmd ;; ListCmdListCmd

Cmd Cmd CmdIf CmdIf CmdWhile CmdWhile CmdRead CmdRead CmdWriteCmdWrite

CmdAtrib CmdAtrib CmdCompCmdComp

Produções da gramática Produções da gramática (continuação 1) (continuação 1) ::

CmdIf CmdIf IFIF ExprExpr THENTHEN CmdCmd

| | IFIF Expr Expr THENTHEN Cmd Cmd ELSEELSE Cmd Cmd

CmdWhile CmdWhile WHILEWHILE Expr Expr DODO CmdCmd

CmdRead CmdRead READREAD ( ( ListId ListId ))

CmdWrite CmdWrite WRITEWRITE (( ListW ListW ))

ListW ListW ElemW ElemW ElemW ElemW ,, ListW ListW

ElemW ElemW Expr Expr CADEIACADEIA

CmdAtrib CmdAtrib ID :=ID := Expr Expr

Produções da gramática Produções da gramática (continuação 2) (continuação 2) ::

Expr Expr ExprSimpl ExprSimpl ExprSimpl ExprSimpl OPRELOPREL ExprSimplExprSimpl

ExprSimpl ExprSimpl Term Term Term Term OPADOPAD ExprSimpl ExprSimpl

Term Term Fat Fat Fat Fat OPMULTOPMULT Term Term

Fat Fat IDID CTECTE (( Expr Expr )) TRUETRUE FALSEFALSE

OPNEGOPNEG Fat Fat

3.2.2 – Especificações léxicas3.2.2 – Especificações léxicas

Cada Cada átomoátomo tem pelo menos um tem pelo menos um atributoatributo chamado chamado tipotipo

Conforme o Conforme o tipotipo do átomo, ele poderá ter do átomo, ele poderá ter outros atributosoutros atributos

Se o átomo é uma Se o átomo é uma palavra reservadapalavra reservada, seu , seu tipotipo é a própria é a própria palavra reservadapalavra reservada e não há outros e não há outros atributosatributos

Tabela de palavras reservadas:Tabela de palavras reservadas:

3.2.2 – Especificações léxicas3.2.2 – Especificações léxicas

Átomo Átomo identificador:identificador: seu tipo é seu tipo é IDID e seu outro e seu outro atributo é a atributo é a cadeiacadeia de seus caracteres; sua de seus caracteres; sua sintaxe é sintaxe é

letra ( letra | dígito )*letra ( letra | dígito )*

Constantes inteiras:Constantes inteiras: seu tipo é seu tipo é CTECTE e seu e seu outro atributo é o seu outro atributo é o seu valor inteirovalor inteiro; esse valor ; esse valor tem de caber em tem de caber em 4 bytes4 bytes

Cadeias de caracteres:Cadeias de caracteres: vêm entre apóstrofos vêm entre apóstrofos ((‘ ’‘ ’); têm como tipo, ); têm como tipo, CADEIACADEIA, e, como outro , e, como outro atributo, a atributo, a cadeia de seus caracterescadeia de seus caracteres sem os sem os apóstrofosapóstrofos

Tabela dos tipos e atributos dos Tabela dos tipos e atributos dos operadoresoperadores::

OPADOPAD : operador aditivo: operador aditivo

OPMULTOPMULT : operador multiplicativo : operador multiplicativo

OPNEGOPNEG : operador negador: operador negadorOPRELOPREL : operador relacional: operador relacional

Tabela dos tipos dos Tabela dos tipos dos separadoresseparadores (não possuem (não possuem outros atributos): outros atributos):

Os programas em Os programas em Mini-PascalMini-Pascal não têm não têm comentárioscomentários

Espaços em brancoEspaços em branco entre átomos são entre átomos são opcionaisopcionais, com a exceção das , com a exceção das palavras palavras reservadasreservadas

Essas não podem estar Essas não podem estar concatenadasconcatenadas com com outras e com identificadores e constantes inteirasoutras e com identificadores e constantes inteiras

3.3 – 3.3 – Análise Léxica por Análise Léxica por Diagramas de Transições Diagramas de Transições

3.3.1 – Objetivos da análise léxica3.3.1 – Objetivos da análise léxica

Os Os caracterescaracteres do programa são grupados em do programa são grupados em átomosátomos

Os Os átomosátomos têm sua têm sua validadevalidade verificada verificada

Os átomos válidos são Os átomos válidos são classificadosclassificados e recebem e recebem seus seus atributosatributos

Exemplo: Exemplo: Programa para o cálculo do Programa para o cálculo do fatorialfatorial de um numero lido:de um numero lido:

PROGRAM fatorial;PROGRAM fatorial;

VAR n, fat, i: INTEGER;VAR n, fat, i: INTEGER;

BEGIN BEGIN

READ (n); READ (n);

fat := 1; i := 1;fat := 1; i := 1;

WHILE i <= n DO BEGINWHILE i <= n DO BEGIN

fat := fat * i; i := i + 1fat := fat * i; i := i + 1

END;END;

WRITE (‘O fatorial de’, n, ‘ eh ’, fat)WRITE (‘O fatorial de’, n, ‘ eh ’, fat)

END.END.

Tabela de átomos e seus

atributos

3.3.2 – Diagrama de transições3.3.2 – Diagrama de transições

A A estruturaestrutura de um analisador léxico pode ser de um analisador léxico pode ser montada sobre um montada sobre um diagrama de transições diagrama de transições de estadosde estados

O diagrama é O diagrama é uma só entidadeuma só entidade, mas, por , mas, por razões didáticas, está apresentado em razões didáticas, está apresentado em várias várias figurasfiguras

Uma figura para Uma figura para cada transiçãocada transição que parte que parte do do estado inicialestado inicial

Supõe-se que, no Supõe-se que, no estado inicialestado inicial, o analisador , o analisador já tenha em mãos um já tenha em mãos um caracterecaractere

a) Uma letra é o primeiro caracterea) Uma letra é o primeiro caractere

Em cada transição: Em cada transição: CaractereCaractere(s) responsável(eis) (s) responsável(eis) AçõesAções antes da transição antes da transição

Forma Cadeia: Forma Cadeia: introduz caractere numa cadeiaintroduz caractere numa cadeia Pega Caractere: Pega Caractere: lê novo caractere do programa; lê novo caractere do programa;

retorna retorna ‘\0’‘\0’ para para end-of-fileend-of-file Class Cadeia: Class Cadeia: classifica cadeia formadaclassifica cadeia formada Forma Átomo: Forma Átomo: forma novo átomo com o tipo obtido da forma novo átomo com o tipo obtido da

classificação; se for classificação; se for IDID, o atributo será a cadeia , o atributo será a cadeia formadaformada

Possíveis átomos:

Palavra reservadaOPMULT - ANDOPAD - OROPNEG - NOTID - cadeia

b) Um dígito é o primeiro caractereb) Um dígito é o primeiro caractere

Forma número:Forma número: obtém o número inteiro obtém o número inteiro correspondente à cadeia formadacorrespondente à cadeia formada

Forma Átomo:Forma Átomo: forma novo átomo com o número forma novo átomo com o número formado e com o tipo formado e com o tipo CTECTE

Átomo formado:

CTE - número inteiro

c) Um apóstrofo é o primeiro caracterec) Um apóstrofo é o primeiro caractere

Se o fecha-apóstrofo for Se o fecha-apóstrofo for esquecidoesquecido, o resto do , o resto do programa será guardado em programa será guardado em cadeiacadeia

Átomo formado:

CADEIA - cadeia

d) Um dos caracteres + - * / ~ = é o d) Um dos caracteres + - * / ~ = é o primeiroprimeiro

Class Caractere: Class Caractere: classifica caractere lidoclassifica caractere lidoPossíveis átomos:

OPMULT - VEZES OPMULT - DIV OPAD - MAIS OPAD - MENOS OPNEG - NEGOPREL - IGUAL

e) O caractere < é o primeiroe) O caractere < é o primeiroPossíveis átomos:

OPREL - MENIGOPREL - DIFEROPREL - MENOR

f) O caractere > é o primeirof) O caractere > é o primeiro

Possíveis átomos:

OPREL - MAIGOPREL - MAIOR

g) O caractere : é o primeirog) O caractere : é o primeiro

Possíveis átomos:

ATRIBDPONTS

h) Um dos caracteres ; . , ( ) é o primeiroh) Um dos caracteres ; . , ( ) é o primeiro

Possíveis átomos:

PVIRG PONTOVIRG ABPAR FPAR

i) Um dos caracteres ‘\0’, ‘ ’, ‘\n’, ‘\t’, ‘\r’, i) Um dos caracteres ‘\0’, ‘ ’, ‘\n’, ‘\t’, ‘\r’, ou qualquer outro é o primeiroou qualquer outro é o primeiro

Possíveis átomos:

FINAL INVAL

Átomo de tipo FINAL: artificial

3.3.3 – Implementação de um 3.3.3 – Implementação de um diagrama de transições léxicasdiagrama de transições léxicas

Primeiramente, será apresentada uma Primeiramente, será apresentada uma função função mainmain para gerenciar a para gerenciar a classificação de todos classificação de todos os átomosos átomos de um programa em Mini-Pascal de um programa em Mini-Pascal

Essa função tem a Essa função tem a simplessimples finalidade de finalidade de testartestar o analisador léxico o analisador léxico

Ela não será usada quando esse Ela não será usada quando esse analisadoranalisador estiver estiver integrado ao analisador sintáticointegrado ao analisador sintático

void main () {void main () {printf ("A N A L I S E L E X I C A\n\n");printf ("A N A L I S E L E X I C A\n\n");printf ("Nome do arquivo: ");printf ("Nome do arquivo: ");fflush (stdin);fflush (stdin);gets (nomearq);gets (nomearq);program = fopen (nomearq, "r");program = fopen (nomearq, "r");result = fopen ("atomosmp", "w");result = fopen ("atomosmp", "w");atom.tipo = INVAL; atom.tipo = INVAL; carac = carac = NovoCarac ()NovoCarac ();;while(atom.tipo != FINAL){while(atom.tipo != FINAL){

NovoAtomo ();NovoAtomo ();ImprimeAtomo ();}ImprimeAtomo ();}

printf ("\nAnalise do arquivo '%s' encerrada", printf ("\nAnalise do arquivo '%s' encerrada", nomearq);nomearq);printf ("\n\nVer atomos no arquivo 'atomosmp'");printf ("\n\nVer atomos no arquivo 'atomosmp'");getch ();getch ();

}}Variáveis globais:nome nomearq; FILE *program, *result;char carac; atomo atom;char *cadeia;

typedef struct atomo atomo;struct atomo { int tipo; atribatomo atrib;};typedef union atribatomo

atribatomo;union atribatomo {

char *cadeia; long valor;

int atr; char carac;};

NovoAtomo: coloca em atom o tipo e o atributo do próximo átomo do programa; é o centro do analisador léxico

NovoCarac: retorna o próximo caractere lido do programa; retorna ‘\0’ caso seja encontrado end-of-file

A função NovoAtomo:A função NovoAtomo:

Coloca na estrutura Coloca na estrutura atomatom o tipo e o atributo do o tipo e o atributo do próximo átomo encontradopróximo átomo encontrado

Implementa o caminhamento pelo Implementa o caminhamento pelo diagrama diagrama de transições léxicasde transições léxicas

A seguir o A seguir o esquema geralesquema geral de NovoAtomo de NovoAtomo

void NovoAtomo () {void NovoAtomo () {int estado = 1;int estado = 1;if (atom.tipo == ID || atom.tipo == CADEIA)if (atom.tipo == ID || atom.tipo == CADEIA)

free (atom.atrib.cadeia);free (atom.atrib.cadeia);cadeia = malloc(MAXCADEIA*sizeof(char));cadeia = malloc(MAXCADEIA*sizeof(char));*cadeia = 0;*cadeia = 0;while (estado != 3)while (estado != 3)

switch (estado) {switch (estado) {case 1: - - - - - - - - - - ; break;case 1: - - - - - - - - - - ; break;case 2: - - - - - - - - - - ; break;case 2: - - - - - - - - - - ; break;case 4: - - - - - - - - - - ; break;case 4: - - - - - - - - - - ; break;case 5: - - - - - - - - - - ; break;case 5: - - - - - - - - - - ; break;case 6: - - - - - - - - - - ; break;case 6: - - - - - - - - - - ; break;case 7: - - - - - - - - - - ; break;case 7: - - - - - - - - - - ; break;case 8: - - - - - - - - - - ; break;case 8: - - - - - - - - - - ; break;

}}free (cadeia);free (cadeia);

}} Caso o átomo anterior tenha como atributo uma cadeia, ela deve ser desalocada

Preparação para uma eventual formação de cadeia

Depois de formado o átomo, a cadeia é desalocada

Aqui ocorrem as transições de estados e o preparo do átomo

Transições a partir do Estado 1

case 1:case 1:

switch (carac) {switch (carac) {case '\'': - - - - -; estado = 5; break;case '\'': - - - - -; estado = 5; break;case '+': case '-': case '*': case '/': case '~': case '+': case '-': case '*': case '/': case '~': case '=': case ';': case '.': case ',': case '(': case '=': case ';': case '.': case ',': case '(': case ')': case ')':

- - - - -; estado = 3; break;- - - - -; estado = 3; break;case '<': - - - - -; estado = 6; break;case '<': - - - - -; estado = 6; break;case '>': - - - - -; estado = 7; break;case '>': - - - - -; estado = 7; break;case ':': - - - - -; estado = 8; break;case ':': - - - - -; estado = 8; break;case '\0': - - - - -; estado = 3; break;case '\0': - - - - -; estado = 3; break;default:default:

if (isalpha (carac)) {- - - - -; estado = if (isalpha (carac)) {- - - - -; estado = 2;}2;}

else if (isdigit (carac)) else if (isdigit (carac)) {- - - - -; estado = 4;}{- - - - -; estado = 4;}

else if ((isspace(carac) || iscntrl(carac)) else if ((isspace(carac) || iscntrl(carac)) && && (carac != 0)) {(carac != 0)) {

- - - - -; estado = 1;- - - - -; estado = 1;}}else {- - - - -; estado = 3; }else {- - - - -; estado = 3; }

}}break;break;

case 1:case 1:

switch (carac) {switch (carac) {

default:default:

if (isalpha (carac)) {if (isalpha (carac)) {

FormaCadeia (); carac = NovoCarac();FormaCadeia (); carac = NovoCarac();

estado = 2;}estado = 2;}

else if (isdigit (carac)) {else if (isdigit (carac)) {

FormaCadeia (); carac = NovoCarac();FormaCadeia (); carac = NovoCarac();

estado = 4;}estado = 4;}

case 1:case 1:

switch (carac) {switch (carac) {

case '\'': case '\'':

carac = NovoCarac( ); estado = 5; carac = NovoCarac( ); estado = 5;

break;break;

case 1:case 1:

switch (carac) {switch (carac) {

case '+': case '-': case '*': case '/': case '~': case '+': case '-': case '*': case '/': case '~': case '=': case ';': case '.': case ',': case '(': case '=': case ';': case '.': case ',': case '(': case ')': case ')':

atom = Classifica (); carac = NovoCarac();atom = Classifica (); carac = NovoCarac();

estado = 3; break;estado = 3; break;

case 1:case 1:

switch (carac) {switch (carac) {

case '<': carac = NovoCarac(); estado = 6; break;case '<': carac = NovoCarac(); estado = 6; break;

case '>': carac = NovoCarac(); estado = 7; break;case '>': carac = NovoCarac(); estado = 7; break;

case ':': carac = NovoCarac(); estado = 8; break;case ':': carac = NovoCarac(); estado = 8; break;

case 1:case 1:

switch (carac) {switch (carac) {case '\0': atom.tipo = FINAL; estado = 3; break;case '\0': atom.tipo = FINAL; estado = 3; break;default: if -----default: if -----

else if ((isspace(carac) || iscntrl(carac)) else if ((isspace(carac) || iscntrl(carac)) && && (carac != 0)) {(carac != 0)) {

carac = NovoCarac(); estado = 1;}carac = NovoCarac(); estado = 1;}else {atom.tipo = INVAL;else {atom.tipo = INVAL;

atom.atrib.carac = carac;atom.atrib.carac = carac; carac = NovoCarac(); estado = 3; }carac = NovoCarac(); estado = 3; }

case 2:case 2:if (isalnum (carac)) {if (isalnum (carac)) {

FormaCadeia (); carac = NovoCarac(); estado = 2;}FormaCadeia (); carac = NovoCarac(); estado = 2;}else {else {

atom = ClassificaCadeia (); estado = 3;}atom = ClassificaCadeia (); estado = 3;}break;break;

case 4:case 4:if (isdigit (carac)) {if (isdigit (carac)) {

FormaCadeia (); carac = NovoCarac();estado = 4;}FormaCadeia (); carac = NovoCarac();estado = 4;}else {atom = FormaNumero (); estado = 3;}else {atom = FormaNumero (); estado = 3;}break;break;

case 6:case 6:if (carac == '=') {if (carac == '=') {

atom.tipo = OPREL; atom.atrib.atr = MENIG;atom.tipo = OPREL; atom.atrib.atr = MENIG;carac = NovoCarac();}carac = NovoCarac();}

else if (carac == '>'){else if (carac == '>'){atom.tipo = OPREL; atom.atrib.atr = DIFER;atom.tipo = OPREL; atom.atrib.atr = DIFER;carac = NovoCarac();}carac = NovoCarac();}

else {else {atom.tipo = OPREL; atom.atrib.atr = MENOR;atom.tipo = OPREL; atom.atrib.atr = MENOR;

}}estado = 3; break;estado = 3; break;

Outros estados ficam como exercícios

Funções auxiliares:Funções auxiliares:

void FormaCadeia (void):void FormaCadeia (void): Armazena o novo caractere lido no final da variável Armazena o novo caractere lido no final da variável

cadeiacadeia É chamada para formar a cadeia de um É chamada para formar a cadeia de um

identificador, palavra reservada, número ou identificador, palavra reservada, número ou constante cadeia de caracteres, ou um dos constante cadeia de caracteres, ou um dos operadores and, or ou notoperadores and, or ou not

atomo ClassificaCadeia (void):atomo ClassificaCadeia (void): Classifica uma cadeia de caracteresClassifica uma cadeia de caracteres Possíveis classes: Possíveis classes:

• IdentificadorIdentificador• Uma das palavras reservadasUma das palavras reservadas• Um dos operadores and, or e not;Um dos operadores and, or e not;

Retorna o átomo formado (tipo e atributo)Retorna o átomo formado (tipo e atributo)

Funções auxiliares:Funções auxiliares:

atomo FormaNumero (void):atomo FormaNumero (void): Converte uma cadeia de dígitos decimais em seu Converte uma cadeia de dígitos decimais em seu

valor numéricovalor numérico Retorna o átomo formado (tipo e atributo)Retorna o átomo formado (tipo e atributo)

atomo Classifica (void): atomo Classifica (void): Classifica átomos formados por apenas um Classifica átomos formados por apenas um

caractere, exceto os inválidoscaractere, exceto os inválidos Retorna o átomo formado (tipo e atributo se for o Retorna o átomo formado (tipo e atributo se for o

caso)caso)

int PalavraReserv (void):int PalavraReserv (void): Verifica se uma cadeia é uma palavra reservadaVerifica se uma cadeia é uma palavra reservada Retorna seu tipo, em caso positivoRetorna seu tipo, em caso positivo

Definição de Definição de constantes simbólicasconstantes simbólicas para as para as palavras reservadas, para os outros tipos de palavras reservadas, para os outros tipos de átomos e para os atributos dos operadoresátomos e para os atributos dos operadores (#defines):(#defines):

3.4 – 3.4 – Análise Sintática por Análise Sintática por Diagramas de Transições Diagramas de Transições

3.4.1 – Objetivos da análise sintática3.4.1 – Objetivos da análise sintática

Verificar a Verificar a estrutura sintáticaestrutura sintática de um de um programaprograma

Servir de Servir de esqueletoesqueleto para: para:

Construção da tabela de símbolosConstrução da tabela de símbolos Análise semânticaAnálise semântica Geração do código intermediárioGeração do código intermediário

Exemplo: Exemplo: árvore sintática do programa do árvore sintática do programa do fatorial (várias figuras)fatorial (várias figuras)

3.4.2 – Diagramas de transições3.4.2 – Diagramas de transições

Análise sintática por Análise sintática por diagramas de diagramas de transiçõestransições é um método é um método top-down preditortop-down preditor::

- Top-down:Top-down: Partindo do Partindo do símbolo inicialsímbolo inicial, , através de derivações diretas, vai através de derivações diretas, vai simulando a construção do programa simulando a construção do programa analisadoanalisado

- Preditor:Preditor: Um só átomo é suficiente para Um só átomo é suficiente para decidir qual produção usar para fazer uma decidir qual produção usar para fazer uma derivação diretaderivação direta

Características de um métodoCaracterísticas de um método preditor:preditor:

- Os átomos são analisados Os átomos são analisados um por umum por um, do , do início para o final do programainício para o final do programa

- Para decidir qual produção usar numa Para decidir qual produção usar numa derivação direta, derivação direta, não é necessário checar não é necessário checar um átomo já analisadoum átomo já analisado

- Não é necessário olhar para algum Não é necessário olhar para algum átomoátomo que que vai aparecer vai aparecer mais adiantemais adiante

- A gramática não pode ser A gramática não pode ser recursiva à recursiva à esquerdaesquerda

- A gramática deve estar A gramática deve estar fatorada à esquerdafatorada à esquerda (assunto a ser estudado no capítulo sobre (assunto a ser estudado no capítulo sobre análise sintática)análise sintática)

A gramática do A gramática do Mini-PascalMini-Pascal admite análise admite análise sintática sintática preditorapreditora, tal como o método dos , tal como o método dos diagramas de transiçõesdiagramas de transições

Muitas gramáticas Muitas gramáticas não admitemnão admitem métodos métodos preditorespreditores

Requerem a análise de Requerem a análise de átomos futurosátomos futuros e/ou e/ou passadospassados

Usa-se Usa-se um diagrama para cada não-um diagrama para cada não-terminalterminal

Nas transições, usa-se Nas transições, usa-se terminaisterminais ou ou não-não-terminais terminais (na análise léxica: caracteres)(na análise léxica: caracteres)

Exemplo para não-terminais:Exemplo para não-terminais: sejam as sejam as produções:produções:

Y → . . . . . . X . . . . . X → . . . . . . Y → . . . . . . X . . . . . X → . . . . . . XPercorrer diagrama

de XDiagrama de Y

Diagrama de X

A seguir, diagramas de A seguir, diagramas de transições sintáticas transições sintáticas de cada não-terminalde cada não-terminal da gramática do da gramática do Mini-Mini-PascalPascal

Incluídas transições para Incluídas transições para tratamento de tratamento de erros sintáticoserros sintáticos

Tal tratamento é Tal tratamento é bem simplesbem simples, só a título de , só a título de ilustraçãoilustração

a)

a)

Pro

gP

rog

P

RO

GR

AM

I

D

PR

OG

RA

M I

D

PV

IRG

PV

IRG

D

ecl

sD

ecl

s

C

md

Com

pC

md

Com

p

P

ON

TO

F

INA

LP

ON

TO

F

INA

L

a)a) ProgProg PROGRAM ID PVIRGPROGRAM ID PVIRG DeclsDecls CmdCompCmdComp PONTO FINALPONTO FINAL

ExecTransic (X):

Percorre o diagrama de X, antes de mudar de estado

Estados 9 e 10:

Tratamento de erro

Incondicional:

Mudança incondicional de estado

b)b) Decls Decls εε VARVAR ListDeclListDecl

c)c) ListDecl ListDecl DeclTipoDeclTipo DeclTipoDeclTipo ListDeclListDecl

Para facilitar a construção do diagrama, pode-se Para facilitar a construção do diagrama, pode-se escrever suas produções de outra maneira:escrever suas produções de outra maneira:

ListDecl ListDecl ( ( DeclTipoDeclTipo )+ )+

d)d) DeclTipo DeclTipo ListId ListId DPONTSDPONTS Tip Tip PVIRGPVIRG

e)e) ListId ListId IDID ID VIRGID VIRG ListIdListId

Pode-se escrever suas produções de outra maneira:Pode-se escrever suas produções de outra maneira:

ListId ListId IDID ( ( VIRG VIRG IDID )*)*

f)f) Tip Tip INTEGERINTEGER BOOLEANBOOLEAN

g)g) CmdComp CmdComp BEGINBEGIN ListCmd ListCmd ENDEND

h)h) ListCmd ListCmd CmdCmd CmdCmd PVIRGPVIRG ListCmdListCmd

Pode-se escrever suas produções de outra maneira:Pode-se escrever suas produções de outra maneira:

ListCmd ListCmd Cmd Cmd ( ( PVIRGPVIRG CmdCmd )* )*

i)i) C

md

C

md

C

md

If

Cm

dIf

C

md

Wh

ile

Cm

dW

hil

e

C

md

Read

C

md

Read

C

md

Wri

te

Cm

dW

rite

||

Cm

dA

trib

C

md

Atr

ib

C

md

Com

pC

md

Com

p

i)i) Cmd Cmd CmdIf CmdIf CmdWhile CmdWhile CmdRead CmdRead CmdWrite CmdWrite || CmdAtrib CmdAtrib CmdCompCmdComp

j)j) CmdIf CmdIf IFIF ExprExpr THENTHEN CmdCmd| | IFIF Expr Expr THENTHEN Cmd Cmd ELSEELSE CmdCmd

■Ambiguidade:Ambiguidade: a sub-forma sentencial a sub-forma sentencial

IFIF Expr Expr THEN IFTHEN IF Expr Expr THENTHEN Cmd Cmd ELSEELSE CmdCmd

tem duas árvores sintáticastem duas árvores sintáticas

■Regra de solução:Regra de solução: o ELSE corresponde ao o ELSE corresponde ao último THEN encontrado último THEN encontrado

■O O diagrama de transiçõesdiagrama de transições resolve o problema resolve o problema

j)j) CmdIf CmdIf IFIF ExprExpr THENTHEN CmdCmd| | IFIF Expr Expr THENTHEN Cmd Cmd ELSEELSE CmdCmd

k)k) CmdWhile CmdWhile WHILEWHILE ExprExpr DODO CmdCmd

l)l) CmdRead READ ABPAR ListId FPAR

m)m) CmdWrite WRITE ABPAR ListW FPAR

n)n) ListW ListW ElemWElemW ElemWElemW VIRGVIRG ListWListW

Pode-se escrever suas produções de outra maneira:Pode-se escrever suas produções de outra maneira:

ListW ListW ElemW ElemW ( ( VIRGVIRG ElemW ElemW )* )*

o)o) ElemW CADEIA Expr

p)p) CmdAtrib ID ATRIB Expr

q)q) Expr ExprSimpl ExprSimpl OPREL ExprSimpl

Pode-se escrever suas produções de outra maneira:Pode-se escrever suas produções de outra maneira:

Expr ExprSimpl ( OPREL ExprSimpl ) ?

r)r) ExprSimpl ExprSimpl TermTerm TermTerm OPADOPAD ExprSimplExprSimpl

Pode-se escrever suas produções de outra maneira:Pode-se escrever suas produções de outra maneira:

ExprSimpl ExprSimpl Term Term ( ( OPADOPAD Term Term )* )*

s)s) Term Term FatFat FatFat OPMULTOPMULT TermTerm

Pode-se escrever suas produções de outra maneira:Pode-se escrever suas produções de outra maneira:

Term Term Fat Fat ( ( OPMULTOPMULT Fat Fat )* )*

t)t) F

at

Fat

IDID

C

TE

CT

E

TR

UE

TR

UE

F

AL

SE

FA

LS

E

A

BP

AR

A

BP

AR

E

xpr

E

xpr

FP

AR

FP

AR

O

PN

EG

O

PN

EG

F

at

Fat

t)t) Fat Fat IDID CTECTE TRUETRUE FALSEFALSE ABPAR ABPAR Expr Expr FPARFPAR OPNEG OPNEG FatFat

3.4.3 – Implementação dos diagramas 3.4.3 – Implementação dos diagramas de transições sintáticasde transições sintáticas

Primeiramente, uma Primeiramente, uma função mainfunção main para para acionar o analisador sintáticoacionar o analisador sintático

void main () {void main () {printf ("A N A L I S E S I N T A T I C A\n\n");printf ("A N A L I S E S I N T A T I C A\n\n");printf ("Nome do arquivo: ");printf ("Nome do arquivo: ");fflush (stdin);fflush (stdin);gets (nomearq);gets (nomearq);program = fopen (nomearq, "r");program = fopen (nomearq, "r");result = fopen ("atomosmp", "w");result = fopen ("atomosmp", "w");erro = FALSE;erro = FALSE;carac = NovoCarac ();carac = NovoCarac ();NovoAtomo ();NovoAtomo ();ExecProg ();ExecProg ();printf ("\nAnalise do arquivo '%s' encerrada", printf ("\nAnalise do arquivo '%s' encerrada", nomearq);nomearq);if (erro)if (erro)

printf ("\n\nPrograma com erros!!!");printf ("\n\nPrograma com erros!!!");printf ("\n\nVer analise no arquivo 'atomosmp'");printf ("\n\nVer analise no arquivo 'atomosmp'");getch ();getch ();

}} Variáveis globais: logic erronome nomearq; FILE *program, *result;char carac; atomo atom;char *cadeia;

ExecProg: implementa o diagrama de transições do não-terminal Prog ; é o centro do analisador sintático

a)A função ExecProg:

void ExecProg () {void ExecProg () {int estado = 1;int estado = 1;while (estado != 8)while (estado != 8)

switch (estado) {switch (estado) {case 1:case 1:

if (atom.tipo == PROGRAM) if (atom.tipo == PROGRAM) {NovoAtomo (); estado = 2;}{NovoAtomo (); estado = 2;}

else {Esperado ("PROGRAM"); estado = else {Esperado ("PROGRAM"); estado = 9;}9;}

break;break;case 2:case 2:

if (atom.tipo == ID) if (atom.tipo == ID) {NovoAtomo (); estado = 3;}{NovoAtomo (); estado = 3;}

else {Esperado ("IDENTIFICADOR"); else {Esperado ("IDENTIFICADOR"); estado = 9;}estado = 9;}

break;break;case 3:case 3:

if (atom.tipo == PVIRG) if (atom.tipo == PVIRG) {NovoAtomo (); estado = 4;}{NovoAtomo (); estado = 4;}

else {Esperado ("PONTO E VIRGULA");else {Esperado ("PONTO E VIRGULA");estado = 9; }estado = 9; }

break;break;

case 4:case 4:ExecDecls ();ExecDecls (); estado = 5; break; estado = 5; break;

case 5:case 5:ExecCmdComp ();ExecCmdComp (); estado = 6; break; estado = 6; break;

case 6:case 6:if (atom.tipo == PONTO) if (atom.tipo == PONTO)

{NovoAtomo (); estado = 7;}{NovoAtomo (); estado = 7;}else {Esperado ("PONTO"); estado = 10;}else {Esperado ("PONTO"); estado = 10;}break;break;

case 7:case 7:if (atom.tipo == FINAL) estado = 8;if (atom.tipo == FINAL) estado = 8;else {Esperado ("END OF FILE"); else {Esperado ("END OF FILE");

estado = 10;}estado = 10;}break;break;

case 9:case 9:if (atom.tipo == PVIRG) if (atom.tipo == PVIRG)

{NovoAtomo (); estado = 4;}{NovoAtomo (); estado = 4;}else if (atom.tipo == FINAL) estado = else if (atom.tipo == FINAL) estado =

8;8;else {NovoAtomo (); estado = 9;}else {NovoAtomo (); estado = 9;}break;break;

case 10:case 10:if (atom.tipo == FINAL) estado = 8;if (atom.tipo == FINAL) estado = 8;else {NovoAtomo (); estado = 10;}else {NovoAtomo (); estado = 10;}break;break;

}}}}

b)b) A função ExecDecls:

void ExecDecls () {void ExecDecls () {

int estado = 11;int estado = 11;

while (estado != 13)while (estado != 13)

switch (estado) {switch (estado) {

case 11:case 11:

if (atom.tipo == VAR) if (atom.tipo == VAR)

{NovoAtomo (); estado = 12;}{NovoAtomo (); estado = 12;}

else estado = 13;else estado = 13;

break;break;

case 12:case 12:

ExecListDecl ()ExecListDecl (); estado = 13;; estado = 13;

break;break;

}}

}}

c)c) A função ExecListDecl:

void ExecListDecl () {void ExecListDecl () {int estado = 14;int estado = 14;while (estado != 16)while (estado != 16)

switch (estado) {switch (estado) {case 14:case 14:

ExecDeclTipo ();ExecDeclTipo (); estado = 15; estado = 15;break;break;

case 15:case 15:if (atom.tipo == ID) estado = 14;if (atom.tipo == ID) estado = 14;else estado = 16;else estado = 16;break;break;

}}}}

d)d) A função DeclTipo:

void ExecDeclTipo () {int estado = 17;while (estado != 21)

switch (estado) {case 17: ExecListId (); estado = 18; break;case 18: if (atom.tipo == DPONTS)

{NovoAtomo (); estado = 19;} else {Esperado ("DOIS PONTOS");

estado = 22;} break;

case 19: ExecTip (); estado = 20; break;case 20: if (atom.tipo == PVIRG)

{NovoAtomo (); estado = 21;} else {Esperado ("PONTO E VIRGULA");

estado = 22;} break;case 22:

if (atom.tipo == PVIRG) {NovoAtomo (); estado = 21;}

else if (atom.tipo == FINAL) estado = 21;

else {NovoAtomo (); estado = 22;} break;

}}

Funções para outros não-terminais ficam como exercícios

3.5 – Tabela de Símbolos em 3.5 – Tabela de Símbolos em Diagramas de Transições Diagramas de Transições

3.5.1 – Objetivos da tabela de símbolos3.5.1 – Objetivos da tabela de símbolos

Agregar informações sobre todos os Agregar informações sobre todos os identificadoresidentificadores do programa do programa

Disponibilizar essas informações para:Disponibilizar essas informações para:– Análise semânticaAnálise semântica– Geração do código intermediárioGeração do código intermediário

Para o Para o Mini-PascalMini-Pascal, considerando só a , considerando só a fase de fase de análiseanálise, as informações são as seguintes:, as informações são as seguintes:

Cadeia de Cadeia de caracterescaracteres do identificador do identificador

TipoTipo do identificador: do identificador:

– Nome de Nome de programaprograma– Nome de Nome de variávelvariável– Nome de Nome de funçãofunção (para o Pascal padrão) (para o Pascal padrão)– Nome de Nome de procedimentoprocedimento (para o Pascal (para o Pascal

padrão)padrão)

Se for Se for variávelvariável::

– TipoTipo da variável (inteira, booleana) da variável (inteira, booleana)– Se é Se é indexadaindexada (para o Pascal padrão) (para o Pascal padrão)– Se tem Se tem inicializaçãoinicialização– Se é Se é referenciadareferenciada

Para a Para a fase de síntesefase de síntese, outras informações: , outras informações:

– Endereço de memóriaEndereço de memória– Número de bytes ocupados, etc. Número de bytes ocupados, etc.

3.5.2 – Estrutura de dados para a tabela 3.5.2 – Estrutura de dados para a tabela de símbolosde símbolos

Pode-se usar estrutura de Pode-se usar estrutura de hashing abertohashing aberto

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

Onde: Onde: – NCLASSHASH é o NCLASSHASH é 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’) )

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

Neste exemplo, as classes têm somente 0 e 1 símbolo; Em outros, as listas das classes podem ser maiores.

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

3.5.3 – Implementação da tabela de 3.5.3 – Implementação da tabela de símbolos em diagramas de transiçõessímbolos em diagramas de transições

A A geraçãogeração da tabela de símbolos é feita nas da tabela de símbolos é feita nas açõesações dos diagramas de transições sintáticas dos diagramas de transições sintáticas

O símbolo com o O símbolo com o nome do programanome do programa é é inserido na produção do não-terminal inserido na produção do não-terminal ProgProg

Ampliado a seguir:

InsereSimb (atom.atrib.cadeia, IDPROG);InsereSimb (atom.atrib.cadeia, IDPROG);

Insere na tabela de símbolos o atributo Insere na tabela de símbolos o atributo cadeiacadeia do átomo recém-formado, como sendo do tipo do átomo recém-formado, como sendo do tipo identificador de programaidentificador de programa

Retorna um Retorna um ponteiroponteiro para a para a célula inseridacélula inserida na tabela de símbolosna tabela de símbolos

Sua programação consiste em Sua programação consiste em inserir inserir numa numa tabela tabela hashinghashing

Os nomes de variáveis são inseridos nas Os nomes de variáveis são inseridos nas transições do não terminal transições do não terminal ListIdListId

O diagrama de O diagrama de ListIdListId é chamado: é chamado:– No diagrama de No diagrama de DeclTipDeclTip, na região das , na região das declaraçõesdeclarações

– No diagrama de No diagrama de CmdReadCmdRead, na região dos , na região dos comandoscomandos

Diagrama de DeclTip

Diagrama de CmdRead

A inserção deve ocorrer na região das A inserção deve ocorrer na região das declaraçõesdeclarações e não na dos e não na dos comandoscomandos

aqui sim

aqui não

Diagrama de DeclTip

Diagrama de CmdRead

Pode-se usar uma variável-flag de nome Pode-se usar uma variável-flag de nome declarandodeclarando (global): (global):

– Na região de declarações:Na região de declarações:declarando = VERDADE;declarando = VERDADE;

– Nas outras regiões:Nas outras regiões:declarando = FALSO;declarando = FALSO;

Em Em ListIdListId , só se deve inserir quando , só se deve inserir quandodeclarando == VERDADEdeclarando == VERDADE

No início da função No início da função ExecProgExecProg (início da análise (início da análise sintática):sintática):

void ExecProg () {void ExecProg () {int estado = 1;int estado = 1;

declarando = FALSO;declarando = FALSO;while (estado != 8)while (estado != 8)

switch (estado) {switch (estado) {

case 1: - - - - - - - - - - - - -case 1: - - - - - - - - - - - - -

No diagrama de No diagrama de Decls Decls ::

No início, No início, declarando = VERDADE;declarando = VERDADE; No final, No final, declarando = FALSO;declarando = FALSO;

No diagrama de No diagrama de ListIdListId , tratamento distinto , tratamento distinto para para

declarando == VERDADEdeclarando == VERDADE declarando == FALSOdeclarando == FALSO

ProcuraSimb (atom . atrib . cadeia):ProcuraSimb (atom . atrib . cadeia):

Procura na tabela de símbolos a célula que Procura na tabela de símbolos a célula que guarda o atributo guarda o atributo cadeiacadeia do átomo recém- do átomo recém-formadoformado

ProcuraSimb (atom . atrib . cadeia):ProcuraSimb (atom . atrib . cadeia):

Quando encontra, retorna um Quando encontra, retorna um ponteiroponteiro para a para a célula procuradacélula procurada; quando não, retorna ; quando não, retorna NULLNULL

Sua programação consiste em procurar numa tabela hashing

ProcuraSimb (atom . atrib . cadeia):ProcuraSimb (atom . atrib . cadeia): Nas declarações, em caso positivo, é uma Nas declarações, em caso positivo, é uma

dupla declaraçãodupla declaração No comando No comando READREAD, em caso negativo, é , em caso negativo, é

identificador usado mas identificador usado mas não declaradonão declarado

Nas declarações, o tipo da variável só aparece Nas declarações, o tipo da variável só aparece mais adiante, fora do diagrama de mais adiante, fora do diagrama de ListId ListId

Podem ser várias variáveis inseridas Podem ser várias variáveis inseridas sem o sem o tipotipo

Solução: colocar os símbolos de uma Solução: colocar os símbolos de uma declaração numa declaração numa lista linear de símboloslista linear de símbolos (lista de ponteiros para células - global)(lista de ponteiros para células - global)

Mais adiante, quando aparecer o Mais adiante, quando aparecer o tipotipo na na declaração, percorre-se essa declaração, percorre-se essa listalista, , adicionando-o em adicionando-o em cada célulacada célula

Exemplo: i, fat, n: INTEGER;Exemplo: i, fat, n: INTEGER;

listsimb:listsimb: variável global variável global

Para adicionar, nas células das Para adicionar, nas células das variáveis variáveis declaradasdeclaradas, a informação sobre o , a informação sobre o tipotipo::

No diagrama de No diagrama de DeclTipDeclTip : :

– A lista global de símbolos é A lista global de símbolos é anuladaanulada e e inicializada inicializada vaziavazia, antes da chamada do , antes da chamada do diagrama de diagrama de ListIdListId

– Depois da chamada do diagrama de Depois da chamada do diagrama de TipTip , , adiciona-se o adiciona-se o tipotipo às referidas células, às referidas células, usando o valor de outra variável global:usando o valor de outra variável global: tipocorrentetipocorrente

Para adicionar, nas células das Para adicionar, nas células das variáveis variáveis declaradasdeclaradas, a informação sobre o , a informação sobre o tipotipo::

E no diagrama de E no diagrama de TipTip : :

AdicTipoVarAdicTipoVar adiciona, em cada símbolo da lista adiciona, em cada símbolo da lista linear, a informação contida na variável global linear, a informação contida na variável global tipocorrentetipocorrente

i, fat, n: INTEGER;

No comando No comando READREAD, a célula com o nome da , a célula com o nome da variável é marcada como variável é marcada como inicializadainicializada e e referenciadareferenciada

No diagrama de No diagrama de CmdAtribCmdAtrib: :

Se encontrado na tabela de símbolos, o Se encontrado na tabela de símbolos, o identificador do lado esquerdoidentificador do lado esquerdo deve ser deve ser marcado como marcado como inicializadoinicializado e como e como referenciadoreferenciado

Se não encontrado, é identificador usado mas Se não encontrado, é identificador usado mas não declaradonão declarado

No diagrama de No diagrama de Fat Fat : :

Se encontrado na tabela de símbolos, o Se encontrado na tabela de símbolos, o identificador identificador deve ser marcado como deve ser marcado como referenciadoreferenciado

Se não encontrado, é identificador Se não encontrado, é identificador usadousado mas mas não declaradonão declarado

3.6 – 3.6 – Testes Semânticos em Testes Semânticos em Diagramas de Transições Diagramas de Transições

3.6.1 – Especificações semânticas do Mini-3.6.1 – Especificações semânticas do Mini-PascalPascal

Qualquer Qualquer identificador de variávelidentificador de variável usado nos usado nos comandos do programa deve estar comandos do programa deve estar declaradodeclarado

Nenhum identificadorNenhum identificador pode ser pode ser declarado mais declarado mais de uma vezde uma vez no programa no programa

Toda variável deve ser Toda variável deve ser inicializadainicializada e e referenciadareferenciada no programano programa

O O nome do programanome do programa não pode ser usado como não pode ser usado como variávelvariável

Especificações relacionadas com expressões:Especificações relacionadas com expressões:

Num comando de Num comando de atribuiçãoatribuição, a expressão e a , a expressão e a variável que recebe seu valor devem ser do variável que recebe seu valor devem ser do mesmo tipomesmo tipo

■ Os operadores Os operadores +, -, ~, *, /+, -, ~, *, / e os e os relacionaisrelacionais <, <, <=, >, >=<=, >, >= só admitem só admitem operandos inteirosoperandos inteiros

■ Os operandos dos operadores Os operandos dos operadores = = ee <> <> devem devem ser de mesmo tiposer de mesmo tipo

Os operadores Os operadores ANDAND, , OROR e e NOTNOT só admitem só admitem operandos booleanosoperandos booleanos

As As expressõesexpressões nos cabeçalhos dos comandos nos cabeçalhos dos comandos IFIF e e WHILEWHILE devem ser devem ser booleanasbooleanas

3.6.2 – Detecção de identificadores de 3.6.2 – Detecção de identificadores de variáveis não-declaradasvariáveis não-declaradas

Ao ser Ao ser usadousado num comando, um identificador num comando, um identificador deve estar na deve estar na tabela de símbolostabela de símbolos

O tipo do identificador deve ser O tipo do identificador deve ser IDVARIDVAR

Um identificador é usado em:Um identificador é usado em:– Comandos Comandos READREAD– Lado esquerdo de comandos de Lado esquerdo de comandos de atribuiçãoatribuição

– FatoresFatores de expressões de expressões

a) Detecção em Comandos READ: no a) Detecção em Comandos READ: no diagrama do diagrama do ListIdListId

b) Detecção no lado esquerdo de um b) Detecção no lado esquerdo de um comando de atribuição:comando de atribuição:

c) Detecção no fator de uma expressão :c) Detecção no fator de uma expressão :

3.6.3 – Detecção de dupla declaração 3.6.3 – Detecção de dupla declaração de identificadoresde identificadores

No diagrama de No diagrama de ListIdListId , ao ser , ao ser declaradodeclarado, um , um identificador não deve estar na identificador não deve estar na tabela de tabela de símbolossímbolos

3.6.4 – Detecção de identificadores não 3.6.4 – Detecção de identificadores não referenciados e não inicializadosreferenciados e não inicializados

Percorrer todas as classes de TabSimb

Visitar célula por célula em cada classe

Reportar aquelas marcadas como não referenciadas e/ou não inicializadas

TabSimb

3.6.5 – Determinação do tipo das 3.6.5 – Determinação do tipo das expressõesexpressões

Os testes semânticos relacionados com expressões Os testes semânticos relacionados com expressões requerem a determinação do requerem a determinação do tipo de expressões e tipo de expressões e sub-expressõessub-expressões::

– Os operadores Os operadores +, -, ~, *, /+, -, ~, *, / e os e os relacionaisrelacionais <, <, <=, >, >=<=, >, >= só admitem só admitem operandos inteirosoperandos inteiros

– Os operandos dos operadores Os operandos dos operadores =, <>=, <> devem ser devem ser de de mesmo tipomesmo tipo

– Os operadores Os operadores ANDAND, , OROR e e NOTNOT só admitem só admitem operandos booleanosoperandos booleanos

– Num comando de Num comando de atribuiçãoatribuição, a expressão e a , a expressão e a variável que recebe seu valor devem ser do variável que recebe seu valor devem ser do mesmo tipomesmo tipo

– As As expressõesexpressões nos cabeçalhos dos comandos nos cabeçalhos dos comandos IFIF e e WHILEWHILE devem ser devem ser booleanasbooleanas

Sejam as seguintes Sejam as seguintes produçõesproduções contendo contendo operadoresoperadores do Mini-Pascal: do Mini-Pascal:

Expr ExprSimpl ( OPREL ExprSimpl )?

ExprSimpl ExprSimpl Term Term ( ( OPADOPAD Term Term )* )*

Term Term Fat Fat ( ( OPMULTOPMULT Fat Fat )* )*

Fat Fat OPNEGOPNEG Fat Fat

Cada Cada OPRELOPREL é cercado por duas é cercado por duas ExprSimplExprSimpl’s’s

Cada Cada OPADOPAD é cercado por dois é cercado por dois TermTerm’s’s

Cada Cada OPMULTOPMULT é cercado por dois é cercado por dois FatFat’s’s

Cada Cada OPNEGOPNEG é seguido por um é seguido por um FatFat

Esses não-terminais representam os operandos de tais operadores

Expr ExprSimpl ( OPREL ExprSimpl )?ExprSimpl ExprSimpl Term Term ( ( OPADOPAD Term Term )* )* Term Term Fat Fat ( ( OPMULTOPMULT Fat Fat )* )*Fat Fat OPNEGOPNEG Fat Fat

Os Os tipos dostipos dos operandosoperandos devem obedecer às devem obedecer às especificações de especificações de compatibilidadecompatibilidade com tais com tais operadoresoperadores

Idéia: Idéia: a execução dos diagramas de a execução dos diagramas de ExprExpr, , ExprSimplExprSimpl, , Term Term e e FatFat pode retornar o pode retornar o tipo da sub-expressãotipo da sub-expressão que representam que representam

int ExecExpr int ExecExpr () {() {int ret;int ret;- - - - - - -- - - - - - -return ret;return ret;

}}

int ExecExprSimpl int ExecExprSimpl () {() {int ret;int ret;- - - - - - -- - - - - - -return ret;return ret;

}}

int ExecTerm int ExecTerm () {() {int ret;int ret;- - - - - - -- - - - - - -return ret;return ret;

}}int ExecFat () int ExecFat ()

{{int ret;int ret;- - - - - - -- - - - - - -return ret;return ret;

}}

ret: variável de retorno

Deve guardar o tipo do não-terminal do diagrama executado

O valor de ret deve ser calculado durante a execução do diagrama

Idéia: Idéia: a execução dos diagramas de a execução dos diagramas de ExprExpr, , ExprSimplExprSimpl, , Term Term e e FatFat pode retornar o pode retornar o tipo da tipo da sub-expressãosub-expressão que representam que representam

Diagrama de Fat (função ExecFat):

Seja cada um dos caminhos que levam, sem erros, ao estado 81

Na produção Na produção Fat Fat IDID::

O tipo de O tipo de FatFat é o tipo da variável representada é o tipo da variável representada por por IDID

Nas produções Nas produções Fat Fat CTECTE | | TRUE TRUE | | FALSEFALSE

O tipos de O tipos de FatFat são respectivamente são respectivamente inteirointeiro, , booleanobooleano e e booleanobooleano::

FALSE

Na produção Na produção Fat Fat ( ( ExprExpr ) )::

O tipo de O tipo de FatFat é o tipo de é o tipo de ExprExpr a ser a ser apresentado adianteapresentado adiante

Produção Produção Fat Fat OPNEGOPNEG Fat Fat : :

É necessário um teste de compatibilidade entre É necessário um teste de compatibilidade entre o atributo de o atributo de OPNEGOPNEG e o tipo de e o tipo de FatFat do lado do lado direitodireito

Se houver compatibilidade, o tipo de Se houver compatibilidade, o tipo de FatFat do do lado esquerdo é o tipo de lado esquerdo é o tipo de FatFat do lado direito do lado direito

Caso contrário, o tipo de Caso contrário, o tipo de FatFat do lado esquerdo do lado esquerdo deve ser o tipo admitido pelo atributo de deve ser o tipo admitido pelo atributo de OPNEGOPNEG

O atributo de O atributo de OPNEGOPNEG pode ser: pode ser:– NOTNOT, que só admite operando booleano, que só admite operando booleano– NEGNEG, que só admite operando inteiro, que só admite operando inteiro

Produção Produção Fat Fat OPNEGOPNEG Fat Fat : :

oper: variável local inteira, para guardar o atributo de um operador

Em caso de erro, retorna-se o tipo admitido pelo atributo de OPNEG

Da análise sintática

Diagrama de Term: Term Term Fat Fat ( OPMULT ( OPMULT Fat Fat )* )*

Ao transitar de 75 para 76 pela primeira vez, não há teste de compatibilidade

Ao voltar de 76 para 75, deve haver teste entre o OPMULT e o Fat anterior

Ao transitar de 75 para 76 depois da primeira vez, deve haver teste entre o Fat e o OPMULT anteriorFunção

ExecTerm

Diagrama de Term: Term Term Fat Fat ( OPMULT ( OPMULT Fat Fat )* )*

Para não haver teste de compatibilidade, ao passar pela primeira vez:

oper = 0, no início de ExecTerm

Diagrama de Term: Term Term Fat Fat ( OPMULT ( OPMULT Fat Fat )* )*

O valor de ret veio de Fat na última transição de 75 para 76

Diagrama de ExprSimpl :

ExprSimpl ExprSimpl Term Term ( OPAD ( OPAD Term Term )* )*

Estratégia análoga ao diagrama de Term

Diagrama de ExprSimpl :

ExprSimpl ExprSimpl Term Term ( OPAD ( OPAD Term Term )* )*

oper = 0, no início de ExecExprSimpl

Diagrama de ExprSimpl :

ExprSimpl ExprSimpl Term Term ( OPAD ( OPAD Term Term )* )*

Diagrama de Expr: Expr ExprSimpl ( OPREL ExprSimpl )?

Ao transitar de 68 para 69 não há teste de compatibilidade

Ao transitar de 69 para 70, deve haver teste entre o OPREL e o ExprSimpl anterior

Ao transitar de 70 para 71, deve haver teste entre o novo ExprSimpl e o OPREL anterior

Diagrama de Expr: Expr ExprSimpl ( OPREL ExprSimpl )?

Diagrama de Expr: Expr ExprSimpl ( OPREL ExprSimpl )?

Diagrama de Expr: Expr ExprSimpl ( OPREL ExprSimpl )?

O tipo de uma expressão relacional é booleano

Diagrama de CmdAtrib: CmdAtrib ID ATRIB Expr

O tipo de Expr deve ser o mesmo da variável correspondente ao ID

Diagrama de CmdAtrib: CmdAtrib ID ATRIB Expr

tvar: variável local destinada a guardar o tipo da variável

Diagrama de CmdAtrib: CmdAtrib ID ATRIB Expr

texpr: variável local destinada a guardar o tipo da expressão

Diagrama de CmdIf:

CmdIf CmdIf IF IF ExprExpr THEN THEN CmdCmd | IF | IF Expr Expr THEN THEN Cmd Cmd ELSE ELSE

CmdCmd

O tipo de Expr deve booleano

Diagrama de CmdIf:

CmdIf CmdIf IF IF ExprExpr THEN THEN CmdCmd | IF | IF Expr Expr THEN THEN Cmd Cmd ELSE ELSE

CmdCmd

Diagrama de CmdWhile:

CmdWhile CmdWhile WHILE WHILE ExprExpr DO DO CmdCmd

O tipo de Expr deve booleano

Diagrama de CmdWhile:

CmdWhile CmdWhile WHILE WHILE ExprExpr DO DO CmdCmd

3.7 – Geração de Código 3.7 – Geração de Código Intermediário Intermediário

Supor que serão utilizadas Supor que serão utilizadas quádruplasquádruplas

A geração das quádruplas deve estar contida A geração das quádruplas deve estar contida nas nas açõesações dos diagramas de dos diagramas de transições transições sintáticassintáticas

Exemplo:Exemplo: Código intermediário não otimizado Código intermediário não otimizado para o programa fatorial:para o programa fatorial:

openmod: aloca memória para as variáveis locais e parâmetros de um módulo

A estrutura de dados para essas quádruplas será vista em capítulo específico.

O código intermediário deve ser otimizado e traduzido para Assembly