Title: Sintaxe de uma Linguagem
1Sintaxe de uma Linguagem
- Especificada através de uma gramática livre de
contexto, BNF (Backus-Naur Form).
2Vantagens 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.
3Analisador Sintático - Parser
Representaçãointermediária
Parsetree
token
Analisador léxico
parser
Resto dofront-end
Programafonte
pede próximotoken
tabela de símbolos
4Tipos 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.
5Parsers 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.
6Tratamento 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.
7Gramáticas Livres de Contexto
- stmt g if expr then stmt else stmt
- 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
8Exemplo 1
- expr g expr op exprexpr g ( expr )expr g -
exprexpr g idop g op g -op g op g
/op g
9Exemplo 1 (notação abreviada)
- expr g expr op expr ( expr ) - expr idop g
- /
10Exemplo 2
- block g begin op_stmts endop_stmts g stmt_list
?stmt_list g stmt_list stmt stmt
11Parse Trees
- Mostra graficamente como o símbolo inicial de uma
gramática deriva uma string da linguagem. - Para uma produção A g XYZ
A
Z
X
Y
12Ambiguidade
- 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.
13Ambiguidade - Exemplo
14Exemplo Duas parse trees
E
E
E
E
E
E
E
E
E
E
id
id
id
id
id
id
15Expressõ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
16Exemplo
- (a b)abb
- A0 g aA0 bA0 aA1A1 g bA2A2 g bA3A3 g ?
17Expressõ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.
18Eliminando Ambiguidades
- stmt g if expr then stmt if expr
then stmt else stmt 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.
19Solução
- stmt g matched_stmt unmatched_stmt
- matched_stmt g if expr then matched_stmt
else
matched_stmt other - unmatched_stmt g if expr then stmt
if expr then matched_stmt
else unmatched_stmt
20Recursã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.
21Recursão à Esquerda - exemplos
- A g A? ?pode ser substituido porA g ?AA g
?A ? - E g E T Tpode ser substituido porE g TEE
g TE ?
22Fatoraçã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.
23Fatoração à Esquerda - exemplo
- stmt g if expr then stmt if expr
then stmt else stmt -
- stmt g if expr then stmt stmt stmt g else stmt
?
24Construções que não podem ser especificadas por
gramáticas livres de contexto
- L wcw w está em (ab)ex declaração de
variáveis antes de seu uso - L anbmcndm n gt 1 e m gt 1ex contagem do
número de argumentos de funções/procedimentos.
25Parsers 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).
26Parsers top-down
- Exemplo reconhecerstmt g if expr then stmt else
stmt while expr do stmt
begin stmt_list end - Pode fazer uso na implementação de diagramas de
transição, ou ser implementado recursivamente.
27Parsers 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.
28Parser bottom-up - exemplo
- S g aABeA g Abc b B g d
- abbcdeaAbcdeaAdeaABeS