Anda di halaman 1dari 32

Compiladores

Departamento de Computação
Universidade Federal de Sergipe

Análise Sintática
Ambiguidade

Prof. Beatriz Trinchão Andrade


beatriz@ufs.br
Ambiguidade

● Uma GLC é ambígua se permitir a construção


de mais de uma derivação à esquerda ou à
direita para a mesma sentença

2
Ambiguidade
● Exemplo:
E → E + E | E * E | -E | (E) | id

id + id * id
– Derivações mais à esquerda?

3
Ambiguidade
● EX:
E → E + E | E * E | -E | (E) | id

id + id* id

4
Ambiguidade
● EX:
E → E + E | E * E | -E | (E) | id

5
Ambiguidade
● Uma gramática ambígua representa um problema
sério para o analisador sintático
– Não especifica com precisão a sintaxe de um programa

● Podemos compará-las com autômatos não


determinísticos
– Dois caminhos distintos podem aceitar a mesma cadeia

6
Ambiguidade
● A ambiguidade não pode ser removida com a
mesma facilidade que em um autômato não-
determinístico
– Não há algoritmo padrão para fazer isso
– Considerada uma especificação incompleta da sintaxe
de uma linguagem
– Deve ser evitada
● Gramáticas ambíguas sempre falham nos testes
dos algoritmos-padrão de análise sintática
● Técnicas têm sido desenvolvidas para tratar casos
típicos de ambiguidade
7
Eliminando a Ambiguidade

● Métodos básicos
– Regra de Eliminação de Ambiguidade
– Modificação da gramática

8
Eliminando a Ambiguidade

● Regra de Eliminação de Ambiguidade


– Adicionar regras extra-gramaticais para cada caso
de ambiguidade
– Corrige a ambiguidade sem alterar a gramática
– Desvantagem: a estrutura sintática não é mais
determinada apenas pela gramática

9
Eliminando a Ambiguidade

● Modificação da gramática
– Usar uma GLC não ambígua, equivalente à original
– Alterar a gramática para forçar a construção de
uma árvore sintática correta, removendo a
ambiguidade

10
Eliminando a Ambiguidade
● Em ambos os métodos, é preciso decidir qual árvore em
cada caso ambíguo é a correta
– Aquela que reflete corretamente o significado desejado

● Exemplo: precedência de operadores e associatividade

exp → exp op exp | ( exp ) | num


op → + | - | *

35 - 3 * 42 ?
35 - 3 - 42 ?
11
Eliminando a Ambiguidade
● Opção: tornar a operação não associativa
exp → fator op fator | fator
fator → ( exp ) | número
op → + | - | *

● Elimina o problema, mas modifica a linguagem


– 35 - 4 - 42 agora é ilegal
– (35 - 4) - 42 é legal

12
Eliminando a Ambiguidade
● Foco em métodos de reescrita de gramáticas
para remoção de ambiguidades
– Não alterar as cadeias básicas reconhecidas

13
Precedência e Associatividade

● Precedência
– Agrupar os operadores em classes de precedência similar
– Para cada precedência, escrever uma regra distinta

exp → exp soma exp | termo


soma → + | -
termo → termo mult termo | fator
mult → *
fator → ( exp ) | num
14
Precedência e Associatividade
● Multiplicação agrupada na regra termo
● Adição e subtração aparecerão mais próximos
da raiz da árvore, implicando em menor
precedência
– Mais próxima da raiz → precedência mais baixa

● Cascata de precedências

15
Precedência e Associatividade
● Essa gramática ainda é ambígua
– Não especifica a associatividade dos operadores
– Motivo: recursão nos dois lados do operador

● Solução
– Substituir uma das recursões pelo caso base, o que
força os casamentos repetidos para o lado ainda
com a recursão

16
Precedência e Associatividade

● Trocando a regra:
exp → exp soma exp | termo
– Por:
exp → exp soma termo | termo
Torna a adição e subtração associativas à esquerda
– Por:
exp → termo soma exp | termo
Associativa à direita

17
Precedência e Associatividade

● Uma regra recursiva à esquerda torna os


operadores associativos à esquerda
● Uma regra recursiva à direita os faz
associativos à direita

18
Precedência e Associatividade

● Regras que tornam todas as operações


associativas à esquerda

exp → exp soma termo | termo


soma → + | -
termo → termo mult fator | fator
mult → *
fator → ( exp ) | num
19
Precedência e Associatividade

● Como fica a árvore 35 - 3 * 42?


● Como fica a árvore 35 - 3 - 42?

● As cascatas de precedência tornam as árvores


de análise sintática mais complexas
● As árvores de sintaxe abstrata não são afetadas

20
O Problema do Else pendente

● Considere a gramática abaixo


declaração → if-decl | outra
if-decl → if ( exp ) declaração
| if ( exp ) declaração else declaração
exp → 0 | 1

● Essa gramática é ambígua por causa do else


opcional
21
O Problema do Else pendente

● Considere a cadeia
– if (0) if (1) outra else outra
● A escolha de qual é a correta depende de
onde queremos associar o if com o else
● Essa ambiguidade é conhecida como
problema do else pendente

22
O Problema do Else pendente
● Para sabermos qual árvore é a correta, precisamos
considerar as implicações para o significado da
declaração if
● Exemplo em C
if (x != 0)
if (y == 1/x) ok = 1;
else z = 1/x;

● Regra do aninhamento mais próximo


– else é associado ao  if  mais próximo que ainda não tem
else
23
O Problema do Else pendente
● Se quiséssemos, poderíamos associar o else à
primeira declaração if com o uso de chaves
if (x != 0)
{ if (y == 1/x) ok = true; }
else z = 1/x;

24
O Problema do Else pendente
● Uma solução:

declaração → dec_casam
| dec_sem_casam
dec_casam → if ( exp ) dec_casam else dec_casam
| outra
dec_sem_casam → if ( exp ) declaração
| if ( exp ) dec_casam else dec_sem_casam
exp → 0 | 1

25
O Problema do Else pendente

● Isso permite que apenas um dec-casam


ocorra antes de um else em uma declaração if
● Força todas as partes else a casarem assim
que possível
● A regra do aninhamento mais próximo em
geral não é construída

26
O Problema do Else pendente

● Opção preferida é a regra de eliminação de


ambiguidade
● Motivos:
– Reduzir complexidade acrescentada à gramática
– Métodos de análise sintática são fáceis de
configurar para obedecer a regra do aninhamento
mais próximo

27
O Problema do Else pendente
● Resolver o problema na especificação da
sintaxe
– Sempre exigir um else a cada if
– Utilizar uma palavra-chave de marcação de bloco:
● if → end-if

28
Ambiguidade Não-Essencial

● Uma gramática pode ser ambígua e mesmo


assim produzir árvores de sintaxe abstrata
únicas
● Considere os seguintes exemplos
decl-sequencia → decl; decl-sequencia | decl
decl → s

decl-sequencia → decl-sequencia; decl | decl


decl → s
29
Ambiguidade Não-Essencial

● Tanto uma gramática recursiva à esquerda quanto


à direita resultariam na mesma estrutura de árvore
de sintaxe abstrata
● Poderíamos reescrever a gramática da seguinte
forma
seq-decl → seq-decl ; seq-decl | decl
decl → s

● Uma ambiguidade como essa pode ser


denominada ambiguidade não essencial
30
Ambiguidade Não-Essencial
● A semântica associada não depende de
alguma regra de eliminação de ambiguidade
● Exemplo:
– Operações associativas
● Adição aritmética
● Concatenação de cadeia de caracteres

31
Referências
● Louden
– Seção 3.4
● Aho et al.
– Seções 4.1.2 e 4.2.5

32

Anda mungkin juga menyukai