Une image / un lien ci-dessous est fourni (tel quel) pour télécharger la présentation
Politique de téléchargement : le contenu du site vous est fourni TEL QUEL pour votre information et votre usage personnel ; il ne peut être vendu, concédé sous licence ni partagé sur d’autres sites sans l’accord de son auteur.Le contenu vous est fourni TEL QUEL, pour votre information et votre usage personnel uniquement.Téléchargez la présentation en cliquant sur ce lien.Lors du téléchargement, si vous ne parvenez pas à télécharger une présentation, l’éditeur a peut-être supprimé le fichier de son serveur.Pendant le téléchargement, si vous ne parvenez pas à obtenir une présentation, le fichier a peut-être été supprimé par l’éditeur.
Capítulo V – Análise Sintática 5.1 – Classificação dos analisadores sintáticos 5.2 – Tratamento de gramáticas 5.3 – Escolha de uma derivação 5.4 – Análise top-down 5.5 – Análise bottom-up 5.6 – Complementos de Yacc
5.1 – Classificação dos Analisadores Sintáticos • Papel do analisador sintático (visto anteriormente): • Verificar a estrutura sintática de um programa • Detectar, sinalizar e tratar erros sintáticos • Servir de esqueleto para o front-end
Classesde métodos de análise sintática: • Analisadores universais • Analisadores top-down • Analisadores bottom-up • Analisadores universais: • Conseguem analisar qualquer GLC • São muito ineficientes para uso em compiladores
Analisadores top-down e bottom-up: • Varrem o programa da esquerda para a direita, um símbolo de cada vez; alguns deles por vezes precisam voltar da direita para a esquerda • Englobam os métodos mais comumente usados em compiladores • Os métodos mais eficientes trabalham apenas com subclasses de gramáticas • Várias dessas subclasses (gramáticas LL e LR, descritas mais adiante) conseguem descrever a maioria das construções sintáticas das linguagens de programação
Analisadores top-down: • Caminham pela árvore sintática dos programas, da raiz para as folhas • Trabalham com gramáticas LL (Left-Left) • Englobam os métodos preditores, dentre os quais, os diagramas de transições • As implementações manuais utilizam métodos top-down
Analisadores bottom-up: • Caminham pela árvore sintática dos programas, das folhas para a raiz • Trabalham com gramáticas LR (Left-Right) • Englobam importantes métodos: • Análise de precedência de operadores • Análise LR • São muito usados na geração automática de analisadores sintáticos
5.2 – Tratamento de Gramáticas • Métodos de análise sintática se aplicam a determinadas classes de GLC’s • Algumas gramáticas devem ser alteradas para que um método possa ser aplicado • É a busca por uma GLCequivalente à original • Duas GLC’s são equivalentes quando geram a mesma linguagem
5.2.1 – Eliminação de ambiguidades • Alguns métodos de análise sintática exigem que a gramática seja não-ambígua • Outros métodos mantém a ambiguidade das gramáticas e usam regras para eliminar árvores sintáticas indesejáveis
Exemplo: comando IF-ELSE da Linguagem C • Produções típicas: Cmd IF ExprCmd| IF ExprCmd ELSE Cmd |c1 | c2 • A sentença: IF e1 IF e2 c1 ELSE c2 tem duas árvores sintáticas:
A regra usual para resolver a ambiguidade é fazer o ELSE corresponder ao segundo IF • Esta regra pode ser incorporada à gramática • Gramática equivalente: CmdCmdCasado|CmdNãoCasado CmdCasado IF ExprCmdCasadoELSE CmdCasado | c1 | c2 CmdNãoCasado IF ExprCmd | IF ExprCmdCasadoELSE CmdNãoCasado
CmdCmdCasado|CmdNãoCasado CmdCasado IF ExprCmdCasadoELSE CmdCasado | c1 | c2 CmdNãoCasado IF ExprCmd | IF ExprCmdCasadoELSE CmdNãoCasado • CmdCasado nunca produz IF sem ELSE • Esta gramática impede o aparecimento de comandos não-casados entre Expr e ELSE
CmdCmdCasado|CmdNãoCasado CmdCasado IF ExprCmdCasadoELSE CmdCasado | c1 | c2 CmdNãoCasado IF ExprCmd | IF ExprCmdCasadoELSE CmdNãoCasado • Essa nova gramática dificultaanálise preditora: • Em Cmd, se aparecer um IF, qual das duas produções tomar? • Cada tipo de ambiguidade deve ser eliminada mediante um tratamento particular
5.2.2 – Eliminação de recursividade à esquerda • Uma GLC é recursiva à esquerda, se tiver um não-terminal A tal que haja uma derivação A + A, onde (N )* • Os métodos de análise top-down não conseguem trabalhar com gramáticas recursivas à esquerda
Exemplo: sejam as produções ExprTermExpr + Term • Num método top-down típico, há um procedimento para cada um dos não-terminais Expr e Term: Expr ( ) { if ( func (átomos analisados e/ou futuros) == TRUE ) { Expr ( ); if (atom != ‘+’) erro (“+ esperado”) elseTerm ( ); } elseTerm ( ); }
Expr ( ) { if ( func (átomos analisados e/ou futuros) == TRUE ) { Expr ( ); if (atom != ‘+’) erro (“+ esperado”) elseTerm ( ); } elseTerm ( ); } • Casofunc (átomos analisados e/ou futuros) seja TRUE, na chamada interna de Expr, os átomos serão os mesmos • O valor de func se repete, resultando em infinitas chamadas recursivas
Para aplicar um método top-down, toda recursividade à esquerda deve ser eliminada da gramática • Há recursividade imediata e não-imediata à esquerda • Exemplos: Imediata: S S b S a Não-imediata: S Aa b , A Sc d
a) Recursividade imediata à esquerda: • É o caso de uma produção ser recursiva à esquerda • Um caso bem simples é o das seguintes produções: A A (, (N )* e não iniciam com A) • Estas produções podem ser substituídas pelas seguintes: A R RR ε que geram as mesmas formas sentenciais que as originais, conforme o próximo slide
Exemplo: seja a seguinte gramática, com duas produções contendo recursividade imediata à esquerda: Expr Expr+ Termo Termo Termo Termo * Fator Fator Fator ( Expr) ID Transformação da gramática: Expr Termo Eaux Eaux + Termo Eaux ε Termo Fator Taux Taux * Fator Taux ε Fator ( Expr) | ID {A A} {A R R R ε} Nas produções de Expr, substituindo: A por Expr por + Termo por Termo R por Eaux De modo análogo, na produção de Termo
Generalização: várias produções do mesmo não-terminal, com recursividade a esquerda Algoritmo 5.1: As seguintes produções: A A 1 A 2 - - - A m 1 2 - - - n Podem ser substituídas por: A 1 A' 2 A' - - - n A' A' 1 A' 2 A' - - - m A' ε Nenhum ipode ser ε
b) Recursividade não-imediata à esquerda: • O algoritmo a seguir elimina toda recursividade à esquerda de uma gramática • Condições da gramática: não deve ter ciclos nem produções vazias • Gramática sem ciclos: sem derivações da forma A + A • Gramática sem produções vazias: a única produção vazia permitida é S (S: símbolo inicial) e S não aparece do lado direito de qualquer produção • Existem algoritmos para eliminar ciclos e produções vazias de GLC’s
Algoritmo 5.2: eliminação de recursividade à esquerda Arranjar os não-terminais numa ordem A1, A2, ... , An Para (i = 1; i <= n; i++) { Para (j = 1; j <= i-1; j++) { Sendo Aj 1 2 - - - m as produções de Aj, no momento, Substituir cada produção da forma Ai Aj pelas produções Ai 1 2 - - - m } Eliminar as recursividades imediatas a esquerda entre as produções de Ai; }
Exemplo: Eliminar as recursividades à esquerda da gramática: S S a T b c T S d U e f U S g U h i • Renomeando os não-terminais: S = A1, T = A2, U = A3 • A gramática torna-se em: A1 A1 a A2 b c A2 A1 d A3 e f A3 A1 g A3 h i
Para i = 1: • Eliminação das recursividades imediatas à esquerda de A1: A1 A2 b X c X X a X ε Algoritmo 5.1 A A1 1 2 A 1 A' 2 A' A' 1 A' ε A1 A2 b X c X X a X ε A2 A1 d A3 e f A3 A1 g A3 h i Novo estado das produções
Para i = 2, j = 1: • Produções de A2: A2 A1 d A3 e f • Produções de A1no momento: A1 A2 b X c X • Substitui-se A1 d por A2 b X d c X d: Produção da forma A2 A1
Para i = 2: • Eliminação das recursividades imediatas à esquerda de A2: Algoritmo 5.1 A2 c X d Y A3 e Y f Y Y b X d Y ε A A1 1 2 3 A 1 A' 2 A' 3 A' A' 1 A' ε A1 A2 b X c X X a X ε A2 c X d Y A3 e Y f Y Y b X d Y ε A3 A1 g A3 h i Novo estado das produções
Para i = 3, j = 1: • Produções de A3: A3 A1 g A3 h i • Produções de A1no momento: A1 A2 b X c X • Substitui-se A1 g por A2 b X g c X g : A3 A2 b X g c X g A3 h i Produção da forma A3 A1
Para i = 3, j = 2: • Produções de A3: A3 A2 b X g c X g A3 h i • Produções de A2no momento: A2 c X d Y A3 e Y fY • Substitui-se A2 b X g por c X d Y b X g A3 e Y b X g f Y b X g : Produção da forma A3 A2
Para i = 3: • Eliminação das recursividades imediatas à esquerda de A3: A3 c X d Y b X g Z f Y b X g Z c X g Z i Z Z e Y b X g Z h Z ε A A1 A2 1 2 3 4 A 1 A' 2 A' 3 A' 4 A' A' 1 A' 2 A' ε Algoritmo 5.1
Novo estado das produções: A1 A2 b X c X X a X ε A2 c X d Y A3 e Y fY Y b X d Y ε A3 c X d Y b X g Z f Y b X g Z c X g Z i Z Z e Y b X g Z h Z ε
A1 A2 b X c X A2 c X d Y A3 e Y fY A3 c X d Y b X g Z f Y b X g Z c X g Z i Z X a X ε Y b X d Y ε Z e Y b X g Z h Z ε • Restaurando os nomes originais dos não-terminais: S T b X c X T c X d Y U e Y fY U c X d Y b X g Z f Y b X g Z c X g Z i Z X a X ε Y b X d Y ε Z e Y b X g Z h Z ε S = A1, T = A2, U = A3 Não há mais recursividade a esquerda
5.2.3 – Fatoração à esquerda • Sejam as seguintes produções do não-terminal A: A onde , , (N )* e o primeiro símbolo de é diferente do primeiro símbolo de • Para um método preditor, não é claro qual produção usar para expandir A • Pode-se atrasar a decisão, aplicando nesta gramática a seguinte transformação: A A’ , A’
A A A’ , A’ • Isso ainda não garante a possibilidade de aplicação de um método preditor • O primeiro símbolo de e pode ser um não-terminal, permanecendo a indecisão • Fatoração é apenas um passo para adequar gramáticas a um método preditor
5.3 – Escolha de uma Derivação • Mesmo numa GLC não-ambígua, a sequência de derivações diretas para produzir uma sentença pode variar • Exemplo: seja a gramática S ε | S ( S ) A sentença ( ) pode ser gerada pelas seguintes derivações: S S(S) (S) () S S(S) S() () • Essas derivações diferem no trecho marcado
S S(S) (S) () S S(S) S() () • Na primeira, escolheu-se o não-terminal Smais à esquerda para ser expandido • Na segunda, foi escolhido o não-terminal Smais à direita • Simbolicamente S(S) me (S) e S(S) md S() • Ou seja, S(S) deriva diretamente mais à esquerda (S) S(S) deriva diretamente mais à direita S()
Derivação mais à esquerda ou mais à direita: quando todas as derivações diretas forem me ou md • Simbolicamente: *meou *md • No exemplo anterior { S *me ( ) } = { S S(S) (S) ( ) } { S *md ( ) } = { S S(S) S( ) ( ) }
Qualquer árvore sintática tem uma única derivação mais à esquerda e uma única derivação mais à direita • Gramática ambígua – outra definição: produz mais de uma derivação mais à esquerda ou mais à direita para pelo menos uma de suas sentenças • Os analisadores sintáticos mais conhecidos analisam derivações mais à esquerda ou mais à direita dos programas
ETFopmult T ( E ) opmult T ( Topad E ) opmult T ( Fopad E ) opmult T ( id opadE ) opmult T ( id opadT ) opmult T ( id opadF ) opmult T ( id opad id ) opmultT ( id opad id ) opmultFopmult T ( id opad id ) opmultcteopmultT ( id opad id ) opmultcteopmultF ( id opad id ) opmultcteopmult ( E ) ( id opad id ) opmultcteopmult ( Topad E ) ( id opad id ) opmultcteopmult ( Fopad E ) ( id opad id ) opmultcteopmult ( id opadE ) ( id opad id ) opmultcteopmult ( id opadT ) ( id opad id ) opmultcteopmult ( id opadF ) ( id opad id ) opmultcteopmult ( id opadcte ) ( x + y ) * 10 / ( n – 2 ) Analisadores preditores examinam derivações mais a esquerda
ET T opmultF T opmult ( E ) T opmult ( E opadT ) T opmult ( E opadF ) T opmult ( Eopadcte ) T opmult ( Topadcte ) T opmult ( Fopadcte ) Topmult ( id opadcte ) T opmultFopmult ( id opadcte ) Topmultcteopmult ( id opadcte ) Fopmultcteopmult ( id opadcte ) ( E ) opmultcteopmult ( id opadcte ) ( E opadT ) opmultcteopmult ( id opadcte ) ( E opadF ) opmultcteopmult ( id opadcte ) ( Eopad id ) opmultcteopmult ( id opadcte ) ( Topad id ) opmultcteopmult ( id opadcte ) ( Fopad id ) opmultcteopmult ( id opadcte ) ( id opad id ) opmultcteopmult ( id opadcte ) ( x + y ) * 10 / ( n – 2 ) Analisadores bottom-up examinam derivações mais a direita reversas
( x + y ) * 10 / ( n – 2 ) ( idopad id ) opmultcteopmult ( id opadcte ) ( Fopad id ) opmultcteopmult ( id opadcte ) ( Topad id ) opmultcteopmult ( id opadcte ) ( Eopadid ) opmultcteopmult ( id opadcte ) ( E opadF ) opmultcteopmult ( id opadcte ) ( E opad T ) opmultcteopmult ( id opadcte ) ( E )opmultcteopmult ( id opadcte ) Fopmultcteopmult ( id opadcte ) T opmultcteopmult ( id opadcte ) T opmult Fopmult ( id opadcte ) T opmult ( idopadcte ) T opmult ( Fopadcte ) T opmult ( Topadcte ) T opmult ( E opadcte ) T opmult ( E opadF ) T opmult ( E opad T ) T opmult( E )T opmult FTE Em negrito, lados direitos a serem reduzidos
5.4 – Análise Top-Down • Tentativa de construir uma árvore sintática para a sentença analisada, começando da raiz, indo em direção às folhas e criando os nós em pré-ordem Exemplo:
5.4 – Análise Top-Down • Tentativa de construir uma árvore sintática para a sentença analisada, começando da raiz, indo em direção às folhas e criando os nós em pré-ordem • Também: tentativa de achar uma derivação mais à esquerda para a sentença ou programa analisado • Análise preditora: os átomos são analisados linearmente da esquerda para a direita, sem a necessidade de observar átomos futuros e de caminhar de volta, da direita para a esquerda, sobre a sequência de átomos
5.4.1 – Análise backtracking • Por vezes, a produção escolhida para produzir uma derivação direta mais à esquerda não leva à árvore sintática da sentença analisada • Então, o analisador é obrigado a voltar para a esquerda na sequência de átomos e a eliminar uma subárvore da árvore em construção, substituindo-a por outra • Exemplo: seja a gramática S a A d a B A b c B ccdddc A seguir, análise da sentença: w = a c c d
1) Início: Árvore contendo somente o símbolo inicial Cursor na raiz da árvore Cursor no primeiro átomo da sentença S S a A d a B A b c B ccdddc w = a c c d
2) 1a produção para expandir S Liga-se S ao átomo da sentença apontado pelo cursor, pois é diante dele que ocorreu a expansão Cursor da árvore avança em pré-ordem S a A d S a A d a B A b c B ccdddc w = a c c d Os cursores se casam: a = a
4) 1a produção para expandir A Liga-se A ao átomo da sentença apontado pelo cursor, pois é diante dele que ocorreu a expansão Cursor da árvore avança em pré-ordem S a A d b S a A d a B A b c B ccdddc w = a c c d Os cursores não se casam: b ≠ c
Connexion au compte
Connectez-vous pour publier votre contenu sur SlideServe.