Você está na página 1de 12

Definição de uma linguagem

„ Linguagem = sintaxe + semântica


„ Especificação da sintaxe: gramática
livre de contexto, BNF (Backus-Naur
Form)
„ Especificação Semântica: informal
(textual), operacional, denotacional, de
ações.

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
„

lista Æ lista + digito


lista Æ lista - digito
lista Æ digito
digito Æ 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8|9
„ 9-5+2 é uma lista?

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
„

bloco Æ begin op_stmts end


op_stmts Æ stmt_list | ε
stmt_list Æ stmt_list ; stmt | stmt

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

„ cadeia Æ cadeia + cadeia


| cadeia - cadeia
|0|1|2|3|4|5|6|7|
8|9
„ Construa, segundo a gramática acima, a
parse-tree de 9 - 5 + 2.

10 de 24

5
Exemplo: Duas parse trees
„ 9 – 5 + 2

cadeia cadeia

cadeia + cadeia cadeia - cadeia

cadeia - cadeia cadeia + cadeia


2 9
9 5 5 2

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
„

right Æ letter = right | letter


letter Æ a | b | … | z

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

Construindo um parser top-


down
1. Para cada nó n, com um não-terminal
A, selecione uma das produções de A
e construa os filhos de n para os
símbolos à direita da produção.
2. Encontre o próximo nó para o qual
uma sub-árvore deve ser construída.

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

Predictive parsing - Problema


„ Recursão à esquerda leva a loop em
predictive parsers:
expr Æ expr + term | term

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

Usando um analisador léxico


„ Facilita o tratamento de lexemas ao
invés de caracteres:
„ Tratamento de espaços em branco
„ Tratamento de número maiores que 9
(constantes)
„ Reconhecimento de identificadores e
palavras-chave.

24 de 24

12

Você também pode gostar