Download - 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