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

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

Analisador sintático: Tipos de análises sintáticas

Apresentações semelhantes


Apresentação em tema: "Analisador sintático: Tipos de análises sintáticas"— Transcrição da apresentação:

1 Analisador sintático: Tipos de análises sintáticas
Tanto os métodos descendentes como os ascendentes constroem a árvore de derivação da esquerda para direita. A escolha das regras basea-se na cadeia a ser reconhecida, que é lida da esquerda para a direita.

2 Analisador sintático: Análise Sintática Ascendente
Na análise sintática ascendente a construção da árvore de derivação para uma determinada cadeia (lexema) começa pelas folhas da árvore e segue em direção de sua raiz. Caso seja obtida uma árvore cuja raiz tem como rótulo o símbolo inicial da gramática, e na qual a sequência dos rótulos das folhas forma a cadeia dada, então a cadeia é uma sentença da linguagem, e a árvore obtida é a sua árvore de derivação.

3 Analisador sintático: Análise Sintática Ascendente
Embora a árvore de derivação seja usada para descrever os métodos de análise, na prática ela não precisa ser efetivamente construída. A única estrutura de dados necessária para o processo de análise sintática é uma pilha. Guarda informação sobre os nós da árvore de derivação relevantes em cada fase do processo

4 Analisador sintático: Análise Sintática Ascendente
Definição: Redução de uma cadeia → partir das folhas em direção à raiz de uma árvore de derivação. A cada passo, procura-se reduzir uma cadeia (ou sub-cadeia) ao seu símbolo de origem, objetivando-se atingir o símbolo inicial da gramática.

5 Analisador sintático: Análise Sintática Ascendente
Etapas da redução de uma cadeia Toma-se uma determinada cadeia . 2) Procura-se por uma sub-cadeia a1,a2,...an de  que possa ser substituída pelo seu símbolo de origem . Ou seja,  → a1,a2,...an . Assim a1,a2,...an  b = a1  a2.

6 Analisador sintático: Análise Sintática Ascendente
3) Repetir o passo (2) até que  = símbolo inicial da gramática. Caso isso não seja possível, tem-se que a cadeia analisada não pertence a linguagem especificada.

7 Analisador sintático: Análise Sintática Ascendente

8 Analisador sintático: Análise Sintática Ascendente
Outro exemplo a cadeia x = a+a*a e produção Nesse caso, a ordem das regras corresponde a uma derivação à direita, porém de trás para frente

9 Analisador sintático: Análise Sintática Ascendente
Problemas: Os maiores problemas na análise sintática ascendente residem na dificuldade de determinação de qual parcela da cadeia (sub-cadeia) que deverá ser reduzida; Qual será a produção a ser utilizada na redução, para o caso de existirem mais do que uma possibilidade.

10 Analisador sintático: Análise Sintática Descendente
Na análise sintática descendente tem-se procedimento inverso ao da ascendente. Aqui a análise parte da raiz da árvore de derivação e segue em direção as folhas, ou seja, a partir do símbolo inicial da gramática vai-se procurando substituir os símbolos não-terminais de forma a obter nas folhas da árvore a cadeia desejada.

11 Analisador sintático: Análise Sintática Descendente
Etapas da redução de uma cadeia Toma-se uma determinada cadeia b e o símbolo inicial  da gramática. 2) Procura-se por uma regra de derivação que permita derivar  em sua totalidade ou pelo menos se aproximar desta. 3) Repetir o passo (2) até que a cadeia não apresente mais símbolos não terminais, verificando se a cadeia obtida coincide com . Não havendo coincidência, a cadeia analisada não pertence a linguagem especificada.

12 Analisador sintático: Análise Sintática Descendente
Exemplo Considere a seguinte gramática e a cadeia x = a+a*a

13 Analisador sintático: Análise Sintática Descendente

14 Analisador sintático: Análise Sintática Descendente
Problemas: Embora apresente os mesmos problemas que a analise sintática ascendente, implementa facilmente compiladores para linguagens obtidas de gramáticas LL(1) (análise da cadeia da esquerda para a direita e derivações esquerdas observando apenas o primeiro símbolo da cadeia para decidir qual regra de derivação será utilizada).

15 Gramática: Derivações e Precedência

16 Gramática: Ambigüidade
Definição 1 Ambigüidade refere-se geralmente a confusão na GLC Sobrecarga (Overloading) pode criar ambigüidade f(17) Em algumas linguagens, f pode ser uma função ou uma macro Para eliminar ambigüidade é preciso conhecer contexto • Requer valores de declarações • É uma questão de tipo, uma gramática livre de contexto não é suficiente • Requer uma solução extra-gramatical (não em GLC) Ambigüidade: Uma gramática que produz mais de uma árvore de derivação para alguma sentença é considerada ambígua Uma GLC é ambígua se permitir mais de 1 derivação mais à esquerda ou mais de 1 derivação mais à direita para a mesma sentença

17 Gramática: Ambigüidade
Definição 2 • Se uma gramática tem mais do que uma derivação mais à esquerda ou a direita, então a gramática é ambígua • Se houver mais do que uma árvore gramatical, então a gramática é ambígua Exemplo clássico — o problema do if-then-else Esta ambigüidade é de natureza inteiramente gramatical

18 Gramática: Ambigüidade
Esta sentença tem duas derivações producão 2, depois producão 1 produção 1, depois produção 2

19 Gramática: Ambigüidade
Removendo ambigüidade Associar cada else ao then anterior mais próximo ainda não associado if (regra de senso comum) Com esta gramática, o exemplo tem apenas uma derivação

20 Gramática:LL(1) e LR(1):Técnicas de parsing
Top-down parsers (LL(1) derivação mais a esquerda, recursivo descendente) • Inicia na raiz da árvore e cresce em direção as folhas • Obtém uma produção e tenta associar a entrada • Se escolha errada pode tentar retroceder (backtrack) • Algumas gramáticas são livre de retrocesso (parsing preditivos ) • Não podem tratar com gramáticas recursivas a esquerda Bottom-up parsers LR(1) • L é porque a entrada é da esquerda para a direita • R é porque é feito usando derivação mais a direita e o 1 porque avalia um token adiante • Inicia nas folhas e cresce até a raiz • Inicia em um estado válido para os primeiros tokens

21 Gramática: Eliminações
Utiliza Gramáticas Livres de Contexto (GLC) para descrever a sintaxe das construções de linguagem de programação como expressões e comandos Derivações: a partir do símbolo inicial de uma regra, substitui-se um não terminal pelo corpo de uma de suas produções O não terminal em cada passo é escolhido: Em derivações mais à esquerda (lm), o não terminal mais à esquerda em cada forma sentencial sempre é escolhido Em derivações mais à direita (rm), o não terminal mais à direita em cada forma sentencial sempre é escolhido

22 Gramática: Eliminações
Eliminação (fatoração) de recursão à esquerda Métodos de análise descendente não tratam recursões à esquerda - Eliminação de recursão à esquerda imediata:

23 Gramática: Eliminações
Eliminação de recursividade à esquerda

24 Gramática: Eliminações
Exemplo de Fatoração a Esquerda Cmd  if Expr then Cmd else Cmd | if Expr then Cmd | Outro A  a A b • Fatorando a esquerda: Cmd  if Expr then Cmd else Opc | Outro A  b X else Opc  if Expr then Cmd else else Opc |  X  a X | 

25 Gramática: Eliminações

26 Gramática: Eliminações
Fatoração de uma gramática • Elimina indecisão de qual produção aplicar quando duas ou mais produções iniciam com a mesma forma sentencial. Por exemplo

27 Gramática: Eliminações
Algoritmo: - Entrada: gramática G - Saída: gramática G, fatorada à esquerda 1) para cada não terminal A, encontrar prefixo a mais longo e comum a duas ou mais de suas alternativas 2) Se a!=ℇ, então existe um prefixo comum não trivial, substitua todas as produções A, A → aB1 | aB2 | ... | aBn | y, onde y representa todas as alternativas que não começam com a, por: - A→ aA' | y - A‘→ B1 | B2 | ... | Bn

28 Gramática: Eliminações

29 Gramática: Eliminações

30 Gramática: Eliminações

31 Análise Descendente(Top-Down)
• Como implementar um reconhecedor para uma GLC? • Constrói-se a árvore de derivação, lendo a sentença de esquerda para a direita, e substituindo sempre o não-terminal mais à esquerda. • Existe três tipos principais de parser top-down: – Recursivo com retrocesso – Recursivo preditivo – Tabular preditivo.

32 Análise Descendente(Top-Down)

33 Análise Descendente(Top-Down)
Implementação do reconhecedor • Cria-se um procedimento por não-terminal – Ele testa a aplicação de cada produção associada ao não terminal; – Lê no texto de entrada o próximo token • Chama o analisador lexical (yylex()) ! • É necessário lembrar onde se fez uma escolha de uma alternativa, para poder retroceder neste ponto.

34 Análise Descendente(Top-Down)
ReconheceTIPO() { switch(token) { case {integer, char, num}: ReconheceTIPOSIMPLES(); break; case ^: reconhece( id) ; } ReconheceTIPOSIMPLES() { switch(token){ case integer: reconhece(integer); break; case char: reconhece(char); break; case num: reconhece(num); reconhece(pp); reconhece(num); break; default: erro();

35 Análise Descendente(Top-Down)
Observações sobre o método recursivo com retrocesso • É fácil de implementar. • É necessário: 1. Que a gramática não seja recursiva à esquerda • A  Aa se tornará ReconheceA() { ReconheceA();... } • Recursão infinita! 2. Que a gramática seja fatorada à esquerda • Senão, deve-se fazer retrocesso. 3. Que os primeiros terminais deriváveis possibilitem a decisão de uma produção a aplicar! • Não há retrocesso sobre não-terminais...

36 Análise Descendente(Top-Down)
Definição: Conjuntos “First” • First(α): – Definição informal: • conjunto de todos os terminais que começam qualquer seqüência derivável de α.

37 Análise Descendente(Top-Down)
Condição para que se possa usar um analisador preditivo

38 Análise Descendente(Top-Down)

39 Análise Descendente(Top-Down)
O que acontece se   First(A)?

40 Análise Descendente(Top-Down)
Para tratar o caso do ε: o conjunto Follow • Follow(B): – conjunto de terminais que podem aparecer à direita de um não-terminal B em uma sentença válida. – $ passa a denotar um terminal “virtual” que marca o fim da entrada (EOF, CTRL-D,…)

41 Análise Descendente(Top-Down)
Exemplo First/Follow S  A B A  c |  B  cbB | ca First(A) = {c, } Follow(A) = {c} First(B) = {c} Follow(B) = {$} First(S) = {c} Follow(S) = {$}

42 Análise Descendente(Top-Down)

43 Análise Descendente(Top-Down)
Observações First/Follow • Só terminais entram em First e Follow. • O algoritmo de cálculo de First(α): – É trivial quando α é um terminal t. – varre as produções X → tω quando α é um não-terminal X; – Inclui ε apenas quando X pode derivar em ε. • O algoritmo de cálculo de Follow(X) – É reservado aos não-terminais X – Inclui o $ em alguns casos triviais (X == o start S) – Varre as produções onde X aparece à direita (A → ωX ω’) – NUNCA inclui ε

44 Análise Descendente(Top-Down)
Exemplo First/Follow S  XYZ X  aXb |  Y  cYZcX | d Z  eZYe | f First(X) = {a, } Follow(X) = {c, d, b, e, f} First(Y) = {c, d} Follow(Y) = {e, f} First(Z) = {e, f} Follow(Z) = {$, c, d} First(S) = {a, c, d} Follow(S) = {$}


Carregar ppt "Analisador sintático: Tipos de análises sintáticas"

Apresentações semelhantes


Anúncios Google