Departamento de Computação
Universidade Federal de Sergipe
Análise Sintática
Ambiguidade
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
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
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
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 → + | - | *
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
● 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
18
Precedência e Associatividade
20
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;
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
26
O Problema do Else pendente
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
31
Referências
● Louden
– Seção 3.4
● Aho et al.
– Seções 4.1.2 e 4.2.5
32