Escolar Documentos
Profissional Documentos
Cultura Documentos
1 de 24
Um compilador simples
Objetivo: traduzir expressões infixas em
posfixas
9–5+2¨95–2+
Aplicabilidade: computação baseda em
pilha
2 de 24
1
Gramática Livre de Contexto
Possui 4 componentes:
Um conjunto de tokens, símbolos terminais
Um conjunto de símbolos não-terminais
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
3 de 24
Exemplo 1
4 de 24
2
Exemplo 1
9-5+2 é uma lista pois:
9 é uma lista por lista Æ digito pois é
digito.
9-5 é lista por lista Ælista-digito.
9-5+2 é lista por lista Ælista+digito
5 de 24
Exemplo 2
6 de 24
3
Parse Trees
Mostra graficamente como o símbolo
inicial de uma gramática deriva uma
string da linguagem.
Para uma produção A Æ XYZ
A
X Y Z
7 de 24
Parsing
Processo de procurar uma parse-tree
para uma dada string de tokens.
8 de 24
4
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.
9 de 24
Ambiguidade - Exemplo
10 de 24
5
Exemplo: Duas parse trees
9 – 5 + 2
cadeia cadeia
11 de 24
Associatividade de Operadores
+, –, * e / são associativos à esquerda, na
maioria das linguagens de programação:
9–5+2
Atribuição em C e exponenciação são
associativos à direita:
a=b=c
2**3**4
Escreva a gramática de atribuição para o
exemplo acima.
12 de 24
6
Associatividade à direita
13 de 24
Prededência de operadores
9+5*2
* tem maior precedência do que +
Usaremos dois não-terminais para
representar os dois níveis de
precedência em expressões e um outro
para gerar as unidades básicas de
expressões.
14 de 24
7
Precedência de operadores
expr Æ expr + term | expr – term |
term
term Æ term * factor | term / factor |
factor
factor Æ digit | ( expr )
digit Æ 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8
|9
15 de 24
Top-down ou bootom-up
parsers
Refere-se à ordem em que os nós da
parse tree são criados.
Top-down: mais fáceis de escrever “à
mão”
Bottom-up: suportam uma classe maior
de gramáticas e de esquemas de
tradução, e é usado/gerado pelas
ferramentas de geração de parsers.
16 de 24
8
Exemplo: Tipos em Pascal
type Æ simple
| ^ id
| array [ simple ] of type
simple Æ integer
| char
| num dotdot num
17 de 24
18 de 24
9
Construindo um parser top-
down
Para algumas gramáticas basta uma
única travessia da esquerda para a
direita da string de entrada.
Token corrente é chamado de
lookahead symbol.
Exemplo:
array [num dotdot num ] of
integer Exemplo
19 de 24
Backtracking
A escolha de uma produção pode
exigir tentativa-e-erro, voltando para
tentar novas alternativas possíveis.
Predictive-parsing: parsing em que
não ocorre backtracking.
20 de 24
10
Recursive descent parsing
Método de análise sintática top-down em que
um conjunto de procedimentos recursivos é
usado para processar a entrada.
Cada procedimento está associado a um
símbolo não-terminal da gramática.
Predictive parsing é um caso especial de
recursive descent parsing em que o símbolo
lookahead determina sem ambiguidades o
procedimento a ser chamado para cada não-
terminal.
21 de 24
22 de 24
11
Predictive parsing - Solução
Reescrever produções tornando-as
recursivas à direita:
A Æ Aa | b
reescrever para
A Æ bR
R Æ aR | ε
Exemplo: expressão “baaaa”
23 de 24
24 de 24
12