1 / 156

CES-41 COMPILADORES

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

ziarre
Download Presentation

CES-41 COMPILADORES

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. CES-41 COMPILADORES Capítulo III Diagramas de Transições

  2. 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 3.5 – Tabela de símbolos em diagramas de transições 3.6 – Testes semânticos em diagramas de transições 3.7 – Geração de código intermediário

  3. 3.1 – Considerações Iniciais • Diagramas de transições: usados na construção do front-end de um compilador • Forma didática de concepção de um front-end • Há outros métodos mais eficientes, porém menos didáticos • A seguir, análises léxica, sintática e semântica e geração de código intermediário por diagramas de transições • Diagrama de transições léxicas é um autômato finito determinístico

  4. Exemplo: Diagrama de transições para reconhecer constantes numéricas em Fortran d é um dígito genérico

  5. Arcos de qualquer vértice para o vértice Erro não são mostrados, mas existem d é um dígito genérico

  6. Estado não final Estado final d é um dígito genérico

  7. São reconhecidas constantes como: 13, +13, -13, 13., 1.25, .25, -.25, -32.43, 13E-15, 13.E-15, -13.25E+72, .75E5 d é um dígito genérico

  8. Para as transições sintáticas usa-se vários diagramas de transições; um para cada não-terminal • Existem linguagens para as quais é difícil ou até impossível a utilização de diagramas de transições sintáticas • Para ilustrar será utilizada a linguagem Mini-Pascal extraída de Pascal, apresentada logo a seguir

  9. 3.2 – Uma linguagem ilustrativa: Mini-Pascal 3.2.1 – Gramática do Mini-Pascal • A gramática do Mini-Pascal não é recursiva à esquerda, mas apresenta a ambiguidade dos comandos condicionais • Não tem subprogramas, nem variáveis indexadas e seu único comando repetitivo é o while • Não-terminais estão emitálico • Terminais são átomos obtidos do analisador léxico;são apresentados com LETRAS MAIÚSCULAS, ou com os caracteres que os identificam

  10. Produções da gramática: ProgPROGRAM ID;DeclsCmdComp. DeclsεVARListDecl ListDeclDeclTipDeclTipListDecl DeclTipListId:Tip; ListIdIDID,ListId Tip INTEGERBOOLEAN CmdCompBEGINListCmdEND ListCmdCmdCmd;ListCmd CmdCmdIfCmdWhileCmdReadCmdWrite CmdAtribCmdComp

  11. Produções da gramática (continuação 1) : CmdIfIFExprTHENCmd | IFExprTHENCmdELSECmd CmdWhileWHILEExprDOCmd CmdReadREAD( ListId) CmdWriteWRITE(ListW) ListWElemWElemW,ListW ElemWExprCADEIA CmdAtribID :=Expr

  12. Produções da gramática (continuação 2) : ExprExprSimplExprSimplOPRELExprSimpl ExprSimpl Term  Term OPADExprSimpl Term  Fat  Fat OPMULT Term Fat IDCTE(Expr)TRUEFALSE OPNEGFat

  13. 3.2.2 – Especificações léxicas • Cada átomo tem pelo menos um atributo chamado tipo • Conforme o tipo do átomo, ele poderá ter outros atributos • Se o átomo é uma palavra reservada, seu tipo é a própria palavra reservada e não há outros atributos • Tabela de palavras reservadas:

  14. 3.2.2 – Especificações léxicas • Átomo identificador: seu tipo é ID e seu outro atributo é a cadeia de seus caracteres; sua sintaxe é letra ( letra | dígito )* • Constantes inteiras: seu tipo é CTE e seu outro atributo é o seu valor inteiro; esse valor tem de caber em 4 bytes • Cadeias de caracteres: vêm entre apóstrofos (‘ ’); têm como tipo, CADEIA, e, como outro atributo, a cadeia de seus caracteres sem os apóstrofos

  15. Tabela dos tipos e atributos dos operadores: OPAD : operador aditivo OPMULT : operador multiplicativo OPNEG : operador negador OPREL : operador relacional

  16. Tabela dos tipos dos separadores (não possuem outros atributos): • Os programas em Mini-Pascal não têm comentários • Espaços em branco entre átomos são opcionais, com a exceção das palavras reservadas • Essas não podem estar concatenadas com outras e com identificadores e constantes inteiras

  17. 3.3 – Análise Léxica por Diagramas de Transições 3.3.1 – Objetivos da análise léxica • Os caracteres do programa são grupados em átomos • Os átomos têm sua validade verificada • Os átomos válidos são classificados e recebem seus atributos

  18. Exemplo: Programa para o cálculo do fatorial de um numero lido: PROGRAM fatorial; VAR n, fat, i: INTEGER; BEGIN READ (n); fat := 1; i := 1; WHILE i <= n DO BEGIN fat := fat * i; i := i + 1 END; WRITE (‘O fatorial de’, n, ‘ eh ’, fat) END. Tabela de átomos e seus atributos

  19. 3.3.2 – Diagrama de transições • A estrutura de um analisador léxico pode ser montada sobre um diagrama de transições de estados • O diagrama é uma só entidade, mas, por razões didáticas, está apresentado em várias figuras • Uma figura para cada transição que parte do estado inicial • Supõe-se que, no estado inicial, o analisador já tenha em mãos um caractere

  20. a) Uma letra é o primeiro caractere • Em cada transição: • Caractere(s) responsável(eis) • Ações antes da transição

  21. Forma Cadeia: introduz caractere numa cadeia • Pega Caractere: lê novo caractere do programa; retorna ‘\0’ para end-of-file • Class Cadeia: classifica cadeia formada • Forma Átomo: forma novo átomo com o tipo obtido da classificação; se for ID, o atributo será a cadeia formada • Possíveis átomos: • Palavra reservada • OPMULT - AND • OPAD - OR • OPNEG - NOT • ID - cadeia

  22. b) Um dígito é o primeiro caractere • Forma número: obtém o número inteiro correspondente à cadeia formada • Forma Átomo: forma novo átomo com o número formado e com o tipo CTE Átomo formado: CTE - número inteiro

  23. c) Um apóstrofo é o primeiro caractere • Se o fecha-apóstrofo for esquecido, o resto do programa será guardado em cadeia Átomo formado: CADEIA - cadeia

  24. d) Um dos caracteres + - * / ~ = é o primeiro • Class Caractere: classifica caractere lido Possíveis átomos: OPMULT - VEZES OPMULT - DIV OPAD - MAIS OPAD - MENOS OPNEG - NEG OPREL - IGUAL

  25. Possíveis átomos: OPREL - MENIG OPREL - DIFER OPREL - MENOR e) O caractere < é o primeiro

  26. f) O caractere > é o primeiro Possíveis átomos: OPREL - MAIG OPREL - MAIOR

  27. g) O caractere : é o primeiro Possíveis átomos: ATRIB DPONTS

  28. h) Um dos caracteres ; . , ( ) é o primeiro Possíveis átomos: PVIRG PONTO VIRG ABPAR FPAR

  29. Átomo de tipo FINAL: artificial i) Um dos caracteres ‘\0’, ‘ ’, ‘\n’, ‘\t’, ‘\r’, ou qualquer outro é o primeiro Possíveis átomos: FINAL INVAL

  30. 3.3.3 – Implementação de um diagrama de transições léxicas • Primeiramente, será apresentada uma função main para gerenciar a classificação de todos os átomos de um programa em Mini-Pascal • Essa função tem a simples finalidade de testar o analisador léxico • Ela não será usada quando esse analisador estiver integrado ao analisador sintático

  31. typedef struct atomo atomo; struct atomo { int tipo; atribatomo atrib; }; void main () { printf ("A N A L I S E L E X I C A\n\n"); printf ("Nome do arquivo: "); fflush (stdin); gets (nomearq); program = fopen (nomearq, "r"); result = fopen ("atomosmp", "w"); atom.tipo = INVAL; carac = NovoCarac (); while(atom.tipo != FINAL){ NovoAtomo (); ImprimeAtomo ();} printf ("\nAnalise do arquivo '%s' encerrada", nomearq); printf ("\n\nVeratomos no arquivo 'atomosmp'"); getch (); } typedef union atribatomo atribatomo; union atribatomo { char *cadeia; long valor; int atr; char carac; }; Variáveis globais: nome nomearq; FILE *program, *result; char carac; atomo atom; char *cadeia; 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

  32. A função NovoAtomo: • Coloca na estrutura atom o tipo e o atributo do próximo átomo encontrado • Implementa o caminhamento pelo diagrama de transições léxicas • A seguir o esquema geral de NovoAtomo

  33. voidNovoAtomo () { int estado = 1; if (atom.tipo == ID ||atom.tipo == CADEIA) free (atom.atrib.cadeia); cadeia = malloc(MAXCADEIA*sizeof(char)); *cadeia = 0; while (estado != 3) switch (estado) { case 1: - - - - - - - - - - ; break; case 2: - - - - - - - - - - ; break; case 4: - - - - - - - - - - ; break; case 5: - - - - - - - - - - ; break; case 6: - - - - - - - - - - ; break; case 7: - - - - - - - - - - ; break; case 8: - - - - - - - - - - ; break; } free (cadeia); } Preparação para uma eventual formação de cadeia Caso o átomo anterior tenha como atributo uma cadeia, ela deve ser desalocada Aqui ocorrem as transições de estados e o preparo do átomo Depois de formado o átomo, a cadeia é desalocada

  34. Transições a partir do Estado 1

  35. case 1: switch (carac) { case '\'': - - - - -; estado = 5; break; case '+': case '-': case '*': case '/': case '~': case '=': case ';': case '.': case ',': case '(': case ')': - - - - -; estado = 3; break; case '<': - - - - -; estado = 6; break; case '>': - - - - -; estado = 7; break; case ':': - - - - -; estado = 8; break; case '\0': - - - - -; estado = 3; break; default: if (isalpha (carac)) {- - - - -; estado = 2;} elseif (isdigit (carac)) {- - - - -; estado = 4;} elseif ((isspace(carac) ||iscntrl(carac)) && (carac != 0)) { - - - - -; estado = 1; } else {- - - - -; estado = 3; } } break;

  36. case 1: switch (carac) { default: if (isalpha (carac)) { FormaCadeia (); carac = NovoCarac(); estado = 2;} elseif (isdigit (carac)) { FormaCadeia (); carac = NovoCarac(); estado = 4;}

  37. case 1: switch (carac) { case '\'': carac = NovoCarac( ); estado = 5; break;

  38. case 1: switch (carac) { case '+': case '-': case '*': case '/': case '~': case '=': case ';': case '.': case ',': case '(': case ')': atom = Classifica (); carac = NovoCarac(); estado = 3; break;

  39. case 1: switch (carac) { case '<': carac = NovoCarac(); estado = 6; break; case '>': carac = NovoCarac(); estado = 7; break; case ':': carac = NovoCarac(); estado = 8; break;

  40. case 1: switch (carac) { case '\0': atom.tipo = FINAL; estado = 3; break; default: if ----- elseif ((isspace(carac) ||iscntrl(carac)) && (carac != 0)) { carac = NovoCarac(); estado = 1;} else {atom.tipo = INVAL; atom.atrib.carac = carac; carac = NovoCarac(); estado = 3; }

  41. case 2: if (isalnum (carac)) { FormaCadeia (); carac = NovoCarac(); estado = 2;} else { atom = ClassificaCadeia (); estado = 3;} break; case 4: if (isdigit (carac)) { FormaCadeia (); carac = NovoCarac();estado = 4;} else {atom = FormaNumero (); estado = 3;} break;

  42. case 6: if (carac == '=') { atom.tipo = OPREL; atom.atrib.atr = MENIG; carac = NovoCarac();} elseif (carac == '>'){ atom.tipo = OPREL; atom.atrib.atr = DIFER; carac = NovoCarac();} else { atom.tipo = OPREL; atom.atrib.atr = MENOR; } estado = 3; break; Outros estados ficam como exercícios

  43. Funções auxiliares: • voidFormaCadeia (void): • Armazena o novo caractere lido no final da variável cadeia • É chamada para formar a cadeia de um identificador, palavra reservada, número ou constante cadeia de caracteres, ou um dos operadores and, or ou not • atomoClassificaCadeia (void): • Classifica uma cadeia de caracteres • Possíveis classes: • Identificador • Uma das palavras reservadas • Um dos operadores and, or e not; • Retorna o átomo formado (tipo e atributo)

  44. Funções auxiliares: • atomoFormaNumero (void): • Converte uma cadeia de dígitos decimais em seu valor numérico • Retorna o átomo formado (tipo e atributo) • atomo Classifica (void): • Classifica átomos formados por apenas um caractere, exceto os inválidos • Retorna o átomo formado (tipo e atributo se for o caso) • int PalavraReserv (void): • Verifica se uma cadeia é uma palavra reservada • Retorna seu tipo, em caso positivo

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

  46. 3.4 – Análise Sintática por Diagramas de Transições 3.4.1 – Objetivos da análise sintática • Verificar a estrutura sintática de um programa • Servir de esqueleto para: • Construção da tabela de símbolos • Análise semântica • Geração do código intermediário • Exemplo: árvore sintática do programa do fatorial (várias figuras)

More Related