1 / 28

Sintaxe de uma Linguagem

Sintaxe de uma Linguagem. Especificada através de uma gramática livre de contexto, BNF (Backus-Naur Form). Vantagens de usar uma gramática. Uma gramática dá uma especificação precisa e fácil de entender da sintaxe de uma linguagem de programação

oleg
Télécharger la présentation

Sintaxe de uma Linguagem

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. Sintaxe de uma Linguagem • Especificada através de uma gramática livre de contexto, BNF (Backus-Naur Form).

  2. Vantagens de usar uma gramática • Uma gramática dá uma especificação precisa e fácil de entender da sintaxe de uma linguagem de programação • Para algumas classes de gramáticas, é possível gerar automaticamente um parser eficiente. Além disso as ferramentas usadas indicam ambiguidades e outras construções difíceis de serem reconhecidas e que passaram desapercebidas • Tem relação direta com a estrutura da linguagem usada para tradução/compilação. • Fácil de ser estendida/atualizada.

  3. Analisador Sintático - Parser Representaçãointermediária Parsetree token Analisador léxico parser Resto dofront-end Programafonte pede próximotoken tabela de símbolos

  4. Tipos de parsers para gramáticas • Métodos de parsing universais: funcionam para qualquer gramática, mas são muito ineficientes (inviáveis para uso prático). • Top down: constroem as parse trees a partir da raiz em direção às folhas. • Bottom-up: constroem as parse trees a partir das folhas.

  5. Parsers top-down ou bottom-up • Em parsers top-down ou bottom-up a leitura do arquivo é sempre feita da esquerda para a direita, um símbolo de cada vez. • Só funcionam para um subconjunto de gramáticas, que na prática são suficientes para a grande maioria das linguagens de programação.

  6. Tratamento de Erros de Sintaxe • Relatar presença de erros claramente e com precisão • Recuperar-se do erro rapidamente, para possibilitar a detecção de erros subsequentes • Não deve gerar overhead significativo para programas corretos.

  7. Gramáticas Livres de Contexto • stmtgifexprthenstmtelsestmt • Um conjunto de símbolos terminais (tokens). • Um conjunto de símbolos não-terminais (“variáveis”). • Um conjunto de produções, cada produção consiste de um não-terminal. Uma seta, e uma seqüencia de tokens e/ou não terminais • Um não terminal designado como símbolo inicial

  8. Exemplo 1 • exprgexpr op exprexprg(expr)exprg-exprexprgidopg+opg-opg*opg/opg^

  9. Exemplo 1 (notação abreviada) • exprgexpr op expr | (expr)| -expr | idopg+ |- | * | / | ^

  10. Exemplo 2 blockgbeginop_stmtsendop_stmtsgstmt_list | stmt_listgstmt_list;stmt | stmt

  11. Parse Trees • Mostra graficamente como o símbolo inicial de uma gramática deriva uma string da linguagem. • Para uma produção A gXYZ A X Y Z

  12. Ambiguidade • Parse-tree gera uma string, mas uma string pode possuir várias parse-trees, se a gramática for ambígua. • Solução: usar sempre gramáticas não-ambíguas, ou gramáticas ambíguas com informações adicionais sobre como resolver ambiguidades.

  13. Ambiguidade - Exemplo • EgE+E | E*E | - E | (E) | id

  14. Exemplo: Duas parse trees • id + id * id E E E * E E + E E + E E * E id id id id id id

  15. Expressões Regulares x Gramáticas Livres de Contexto • Tudo que pode ser descrito por uma expressão regular pode ser descrito com gramáticas livres de contexto, mas: • As regras léxicas são especificadas mais simplesmente com expressões regulares • Expressões Regulares geralmente são mais concisas e simples de entender • Podem ser gerados analisadores léxicos mais eficientes a partir de expressões regulares • Estrutura/modulariza o front-end do compilador

  16. Exemplo • (a | b)*abb • A0gaA0 | bA0 | aA1A1g bA2A2g bA3A3g

  17. Expressões Regulares x Gramáticas Livres de Contexto • Expressões regulares são convenientes para especificar a estrutura de construções léxicas, como identificadores, constantes, palavras chave etc. • Em geral usa-se gramáticas para especificar estruturas aninhadas, como parenteses, begin-end, if-then-else etc.

  18. Eliminando Ambiguidades • stmtgifexprthenstmt|ifexprthenstmtelsestmt | other • if E1 then S1 else if E2 then S2 else S3 • if E1 then if E2 then S1 else S2 • Nas linguagens de programação normalmente a regra é que o else casa com o then mais próximo.

  19. Solução stmtgmatched_stmt | unmatched_stmt matched_stmtgifexprthen matched_stmtelsematched_stmt|other unmatched_stmtgifexprthenstmt | ifexprthenmatched_stmtelseunmatched_stmt

  20. Recursão à Esquerda • Uma gramática é recursiva à esquerda se existe um não terminal A tal que existe uma derivação de A que gera A, para alguma string . • Existem técnicas/algorítimos para eliminar a recursão à esquerda.

  21. Recursão à Esquerda - exemplos • AgA | pode ser substituido porAgA’A’gA’ |  • EgE + T | Tpode ser substituido porEgTE’E’g+TE’ | 

  22. Fatoração à Esquerda • Técnica de transformação de gramática usada para produzir uma gramática adequada para predictive parsing. • Combina os casos em que há mais de uma alternativa possível a partir do reconhecimento de um token. • Existem técnicas/algorítimos para fazer a fatoração à esquerda.

  23. Fatoração à Esquerda - exemplo • stmtgifexprthenstmt |ifexprthenstmtelsestmt • stmtgifexprthenstmtstmt’stmt’gelsestmt | 

  24. Construções que não podem ser especificadas por gramáticas livres de contexto • L = {wcw | w está em (a|b)*}ex: declaração de variáveis antes de seu uso • L = {anbmcndm | n >= 1 e m >= 1}ex: contagem do número de argumentos de funções/procedimentos.

  25. Parsers top-down • Recursive-descent parsing: técnica de parsing top-down que suporta backtracking • predictive parsing: recursive-descent parsing sem backtracking. • Relativamente fáceis de escrever à mão • Só reconhecem alguns tipos de gramáticas: não suportam recursão à esquerda, precisa fazer fatoração à esquerda (predictive).

  26. Parsers top-down • Exemplo: reconhecerstmtgifexprthenstmtelsestmt | whileexprdostmt | beginstmt_listend • Pode fazer uso na implementação de diagramas de transição, ou ser implementado recursivamente.

  27. Parsers bottom-up • Também chamado de shift-reduce parsing – reduz uma string w ao símbolo inicial da gramática. A redução ocorre através da substituição do lado direito de uma produção pelo não-terminal do seu lado esquerdo. • Mais complexo, constrói a árvore a partir das folhas. • Gerado por ferramentas automáticas.

  28. Parser bottom-up - exemplo • SgaABeAgAbc | b Bgd • abbcdeaAbcdeaAdeaABeS

More Related