A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Construção de Compiladores 1 Relações em uma Gramática Relação Cabeça (Head) É uma das mais simples de identificar e seu nome deve-se ao fato de que um.

Apresentações semelhantes


Apresentação em tema: "Construção de Compiladores 1 Relações em uma Gramática Relação Cabeça (Head) É uma das mais simples de identificar e seu nome deve-se ao fato de que um."— Transcrição da apresentação:

1 Construção de Compiladores 1 Relações em uma Gramática Relação Cabeça (Head) É uma das mais simples de identificar e seu nome deve-se ao fato de que um de seus elementos é a cabeça do lado direito de uma regra. Cabeça: Vn (Vt U Vn) onde = eh formado por Cabeça (A): { | A é uma regra de produção de G} onde A Vn; (Vn U Vt); (Vn U Vt)* onde * = eh regra de producao Exemplo: Seja a gramática G = (Vn, Vt, P, S) onde Vn = {S,A,B} e Vt = {a,b}; P: S AB A aA | a B bB | b As relações cabeça existentes são: Cabeça (S) = {A} Cabeça (A) = {a} Cabeça (B) = {b}

2 Construção de Compiladores 1 Relações em uma Gramática Relação Último (Last) Último: Vn (Vn U Vt) Último (A) = { | A é uma regra de produção de G} onde A Vn (Vn U Vt) (Vn U Vt)* Intuitivamente, a relação último relaciona um dado não terminal, existente do lado esquerdo de uma certa regra, com o último elemento que aparece do lado direito desta regra. No exemplo anterior: Último(S) = {B}; Último(A) = {A, a}; Último(B) = {B, b}

3 Construção de Compiladores 1 Relações em uma Gramática Relação First() A relação Firstk é uma parente próxima da relação Cabeça. É definida para k e N como sendo: Firstk ( ) = {x Vt* | (|x| < k e deriva x) ou (|x| = k e deriva x ) onde (Vn U Vt); (Vn U Vt)*; x Vt* A relação Firstk(a) de uma gramática consiste de todas as cadeias de terminais de tamanho k, que são geradas a partir de, numa seqüência de 0 ou mais produções. Se a deriva, então também está no conjunto Firstk No exemplo anterior: First1 (S) = {a}, First1(A) = {a} e First1 (B) = b

4 Construção de Compiladores 1 Regras para determinar o conjunto First1 (x), para todo símbolo e (Vn U Vt): 1 - Se x é terminal, First1(x) = {x}, pois x deriva x; 2 - Se x é não terminal e x a é uma produção, então acrescente a a First1(x). Se x é uma produção, acrescente a First1(x); 3 - Se x Y1Y2Y3...Yk é uma produção, então para todo i tal que todos Yi...Yi-1 são não terminais e First1(Yj) contém, para j = 1,2,...,i-1 (isto é, Y1Y2...Yi-1 l) acrescente todo símbolo diferente de de First1(Yi) em First1(x). Se First1(Yj) para todo j = 1,2,...,k, então acrescente a First1 (x); Para calcular First1(x1x2..xn) como segue: adicione a First1(x1x2..xn) todos símbolos diferentes de de First1(x1). Se First1(x1) acrescente também todos símbolos diferentes de de First1(x2); se First1(x2) então acrescente também os símbolos diferentes de de First1(x3) e assim por diante Relações em uma Gramática

5 Construção de Compiladores 1 Exemplo: G: E TE' E' +TE' | T FT' T' *FT' | T (E) | id onde Vn = {E,T,F,E',T'} Vt = {(,),id,+,*} S = E Temos: First (E) = First (TE') = First (FT'E') = {(,id} First (E') = {+, } First (T') = {*, } Relações em uma Gramática

6 Construção de Compiladores 1 Relações em uma Gramática Relação Seguidork (Follow) Seja G = (Vn, Vt, P, S) definimos a relação Follow como: Followk (A) = {x e Vt* | (S deriva A e x Firstk ( )} onde A Vn; x Vt*; (Vn U Vt)* Assim, o conjunto Follow1 (A) é o conjunto dos terminais a que podem aparecer imediatamente à direita de A em alguma forma sentencial (" estágio da geração de uma sentença constitui uma forma sentencial), tal que S deriva Aa para algum e. Regras para se determinar o conjunto Follow1 (B), para todo B e Vn: 1 - Se existe uma produção A, então tudo o que estiver em First1 ( ), exceto, está em Follow1 (B); 2 - Se existe uma produção A, ou uma produção A e First1 (isto é, deriva ), então tudo o que estiver em Follow1 (A) está em Follow1 (B);

7 Construção de Compiladores 1 Relações em uma Gramática Exemplo: Considere a gramática do exemplo do First: Então: Follow1 (E) = { ) } Follow1 (T') = First1 (E') = {+} U Follow1 (E') = {+} U Follow1 (E) = {+,)} Follow1 (F) = First1 (T') = {*} U Follow1 (T') = {*} U Follow1 (T) = {*,+,)} Follow1 (E') = Follow1 (E) = { ) } Follow1 (T') = Follow1 (T) = {+, ) }

8 Construção de Compiladores 1 Análise Sintática - IntroduçãoAnalisadorSintático AnalisadorSintático Lista de tokens Árvore Gramatical Árvore Gramatical token Obter próximo token

9 Construção de Compiladores 1 Análise Sintática - Introdução. Funções do Analisador Sintático: - comprovar que a sequência de tokens cumpre as regras gramaticais; - gerar a árvore gramatical..Vantagens de utilizar gramáticas: - especificações sintáticas precisas de linguagens; - podemos usar um gerador automático de parser; - o processo de construção pode levar a identificar ambiguidades; - facilidade de ampliar/modificar a linguagem.

10 Construção de Compiladores 1 Papel dos Analisadores Sintáticos Identificar erros de Sintaxe: A * / B; Tornar clara a estrutura hierárquica da evolução da sentença: A / B * C (A/B) * C em Fortran A / (B*C) em APL Recuperação de erros de sintaxe; Não retardar, de forma significativa, o processamento de programas corretos.

11 Construção de Compiladores 1 Observações 360% dos programas compilados corretos sintaticamente e semanticamente; 380% dos enunciados com erros apresentam apenas um erro; 313% dos enunciados com erros apresentam apenas dois erros; 390% dos erros envolvem um único token.

12 Construção de Compiladores 1 Analisadores Sintáticos - Tipos. Métodos de Cocke-Younger-Kasami e Early:. universais: servem para qualquer gramática (bem eficientes). Métodos Descendentes (Top Down): constroem a árvore sintática de cima para baixo. Analisadores Descendentes Recursivos. Analisadores LL(k). Métodos Ascendentes (Bottom-up):constroem a árvore sintática de baixo para cima. Analisadores SR. Analisadores LR. Analisadores LALR

13 Construção de Compiladores 1 Analisadores Sintáticos - Tipos Tanto para a análise ascendente, quanto para a descendente: - a entrada é examinada da esquerda para a direita, um símbolo por vez; - trabalham com subclasses de gramáticas. Em geral, as gramáticas são LL e LR - na prática, utilizam-se LL(1) e LR(1) Muitos compiladores são dirigidos pela sintaxe (parsen driver), onde o analisador sintático chama o analisador léxico Há ferramentas para geração automática de analisadores sintáticos, como o Yacc e o Bison

14 Construção de Compiladores 1 Recuperação de Erros Desespero Desespero: identificado um erro, o analisador sintático descarta símbolos de entrada, até que seja encontrado um token pertencente ao subconjunto de tokens de sincronização; - tokens de sincronização: delimitadores etc. Recuperação de Frases Recuperação de Frases: ao descobrir um erro, o analisador sintático pode realizar uma correção local na entrada restante (substituir por alguma cadeia que permita a análise prosseguir) - exemplo: substituir uma vírgula inadequada por um ponto e vírgula, remover um : excendente;

15 Construção de Compiladores 1 Recuperação de Erros Produções de Erro Produções de Erro: aumenta-se a gramática, de forma a acomodar os erros mais comuns. Quando uma produção de erro é identificada pelo analisador, diagnósticos apropriados são apresentados; Correção Global Correção Global: usa algoritmos de escolha da sequência mínima de mudanças necessárias para se obter a correção global, com custo adequado. - exemplo: dada uma cadeia x, o parser procura árvores gramaticais que permitam transformar x em y (cadeia correta) com um mínimo de modificações.


Carregar ppt "Construção de Compiladores 1 Relações em uma Gramática Relação Cabeça (Head) É uma das mais simples de identificar e seu nome deve-se ao fato de que um."

Apresentações semelhantes


Anúncios Google