Escolar Documentos
Profissional Documentos
Cultura Documentos
COMPILADORES:
da teoria prtica
CAPTULO 1. INTRODUO
18
dados PPP
H
PP
q HH
H
HH
H
H
programa
interpretador
resultados
dados
programa
executvel
compilador
"
resultados
19
ainda limitada. O problema reside, principalmente, na inexistncia de um acordo sobre quais as frases sintacticamente correctas, nem foi ainda proposta uma gramtica
suficientemente precisa e consensual.
Nesta seco apresentaremos alguns sistemas formais que permitem definir famlias
de linguagens utilizadas frequentemente em computao. A nossa ateno principal
orienta-se para as linguagens livres de contexto, pois so as mais usadas para descrever
a sintaxe das linguagens de computao.
1.2.1 Terminologia
Antes de introduzir a especificao formal de linguagens apresentam-se algumas definies e terminologia.
alfabeto Um alfabeto, designado por , um conjunto finito no vazio de smbolos
indivisveis. Por exemplo, a lingua inglesa contm as 26 letras alfabticas e alguns sinais
de pontuao. A lingua portuguesa usa apenas 23 letras, mas inclui certos smbolos de
acentuao para algumas letras. O alfabeto ASCII ( American Standard Code for Information Interchange ) utiliza 128 smbolos, sendo utilizado na maioria das comunicaes
entre computadores. O alfabeto UNICODE, mais recente que o ASCII, pretende suportar os smbolos de todas as linguagens utilizadas no planeta e possui, no momento da
escrita deste documento, mais de 38 mil smbolos. No entanto, os aspectos mais importantes das linguagens formais podem ser modelados com apenas duas letras.
cadeia Uma cadeia de um alfabeto uma sequncia finita de smbolos de . O
nmero de smbolos na cadeia x designada por comprimento da cadeia e designado
por |x|. A cadeia vazia, de comprimento 0 ( zero ), designada por .
conjuntos de cadeias O conjunto de todas as possveis cadeias de um alfabeto designaremos por , enquanto + designa todas as cadeias no vazias e o conjunto vazio.
linguagem Uma linguagem sobre um alfabeto o conjunto de cadeias consideradas
vlidas sobre esse alfabeto. Os membros da linguagem so tambm designados por
frases da linguagem.
Uma vez que as linguagens so apenas conjuntos aceitvel aplicar as operaes tradicionais, como a unio, interseco e complemento. Alm disso, existem mais duas
operaes base sobre linguagens: a concatenao e o fecho de Kleene.
CAPTULO 1. INTRODUO
20
21
Exemplo 1.1 A gramtica G = ({0, 1, 2}, {S, A}, S, P ), onde P constitudo pelas regras
S
S
2A
0A
1A
0SA2
A2
01
11
As gramticas podem ser divididas em quatro classes de restries gradualmente crescentes forma das regras. Esta classificao designada por hierarquia de Chomsky.
Seja uma gramtica G = (, V, S, P )
1. G tambm designada gramtica tipo-0 ou gramtica sem restries.
2. G tipo-1 ou gramtica dependente do contexto se cada regra de P obedece a || ||. Uma gramtica ainda do tipo-1 se tiver uma regra S , desde
que S no surja no lado direito de nenhuma regra.
3. G tipo-2 ou gramtica livre do contexto se cada regra de P obedece a
|| = 1, ou seja, constitudo por um s no terminal.
4. G tipo-3 ou gramtica regular se cada regra tiver uma das formas A cB, A c
ou A , onde A e B so no terminais ( podendo B = A ) e c um terminal.
Cada classe de linguagens do tipo-i contm a classe de linguagens do tipo-i+1, para
i = 0, 1, 2.
Contudo, as classes de linguagens identificadas por Chomsky no reflectem apenas as
propriedades formais das mesmas mas tambm traduzem as caractersticas fundamentais da sua computao. De facto, cada classe de gramtica processvel por uma classe
de ferramentas,
mquinas de Turing processam gramticas sem restries.
autmatos linearmente limitados processam gramticas dependentes do contexto.
autmatos de pilha processam gramticas livre do contexto.
22
CAPTULO 1. INTRODUO
fecho Uma classe de linguagens diz-se fechada numa operao particular se cada aplicao da operao nas linguagens da classe ainda uma linguagem dessa classe. As
operaes designam operaes de unio, interseco, complemento, concatenao e fecho de Kleene. As propriedades de fecho so teis na construo de novas linguagens a
partir de linguagens existentes e para provar muitas propriedades tericas das linguagens e gramticas.
As gramticas sem restries s no so fechadas pela operao de complemento. As
gramticas livres de contexto no so fechadas pelas operaes de complemento e interseco. Finalmente, as linguagens regulares e as linguagens dependentes do contexto
so fechadas em todas as cinco operaes.
Captulo 2
Linguagens regulares
As linguagens regulares, designadas por tipo-3 na hierarquia de Chomsky ( ver 1.2.2 ),
so linguagens muito simples. Assim, a maioria das linguagens utilizadas em computao no so regulares, ou seja, no podem ser completamente descritas por gramticas
regulares. No entanto, como o seu processamento simples e eficiente, as gramticas regulares so frequentemente utilizadas para processar partes, por vezes significativas, de
linguagens mais complexas. Desta separao do processamento da linguagem por uma
gramtica regular e por outra gramtica, em geral livre de contexto, resulta uma maior
eficincia em termos de espao ocupado pelo analisador e do tempo gasto na anlise das
descries. Resulta, ainda, uma simplificao da gramtica livre de contexto, facilitando
a sua descrio, realizao e execuo.
O processamento da parte regular de uma linguagem designa-se por anlise lexical. A
anlise lexical tem a vantagem de ser um processo que podendo ser formalmente descrito atravs de expresses regulares pode produzir uma rotina que realiza essa anlise.
Essa rotina modela um autmato finito derivado matematicamente das expresses regulares especificadas.
A anlise lexical utilizada essencialmente na categorizao dos elementos de uma linguagem em classes de smbolos, em vez de caracteres individuais. Nomeadamente,
permite separar nomes em palavra reservadas, identificadores e literais, bem como classificar outros smbolos como terminadores, separadores e operadores. Permite ainda
encapsular dependncias do sistema operativo, como por exemplo, o carcter ou caracteres de mudana de linha. Localiza a manipulao dos diferentes formatos de representao de caracteres, como o ASCII, UNICODE ou, no caso da lingua portuguesa, o
ISO-LATIN-15 ou a pgina 860. Esconde do restante compilador elementos como comentrios e caracteres brancos ( em geral designam o espao e o tabulador horizontal ).
Realiza a substituio de macros simples. Em resumo, facilita o processamento transformando uma linguagem descrita por uma sequncia de caracteres numa sequncia de
25
26
elementos lexicais, designados por tokens. A restante anlise da linguagem pode assim
ser baseada em elementos categorizados.
Expresses regulares foram introduzidas em 1956 por Stephen Kleene para o estudo
das propriedades das redes neuronais. As linguagens representadas por expresses regulares so designadas por linguagens regulares. As expresses regulares apresentam
representaes das linguagens que so frequentemente claras e concisas, contudo, muitas linguagens no so regulares.
Uma expresso regular sobre um alfabeto , e a linguagem regular que a expresso
regular representa, pode ser definida por:
1. o smbolo uma expresso regular e representa a linguagem vazia.
2. o smbolo uma expresso regular e representa a linguagem cujo nico membro
a cadeia vazia, ou seja, {}.
3. para cada c , c uma expresso regular e representa a linguagem {c}, onde o
nico membro a cadeia de um s carcter c.
4. se r e s so expresses regulares e representam as linguagens R e S, ento (r|s), (rs)
S
e (r) so expresses regulares que representam R S, RS e R , respectivamente.
Exemplo 2.1 A expresso regular ((0(0|1))|((0|1) 0)) sobre o alfabeto {0, 1} representa a
linguagem regular que consiste em todas as cadeias de digitos binrios que comeam ou terminam
com 0.
De acordo com a definio acima, as expresses regulares so construdas por operadores com determinadas propriedades. A esses operadores atribuiremos prioridades por
forma a simplificar a escrita das expresses regulares. Considerando as propriedades
algbricas dos operadores base possvel introduzir identidades algbricas para expresses regulares por forma a construir expresses equivalentes. Duas ou mais expresses
regulares que representam a mesma linguagem so designadas por equivalentes.
27
Uma expresso regular pode ser formada pelos seguintes operadores, considerando
duas expresses regulares p, q:
unio: designado por p|q comutativo, associativo e idempotente ( p|p = p ), representando a unio das expresses regulares originais. o elemento neutro da unio.
concatenao: designado por p q associativo e distributivo em realo escolha e
mais prioritrio que a escolha. elemento neutro e o elemento absorvente na
concatenao.
fecho de Kleene: designado por p idempotente ( p = p ) e mais prioritrio que
a concatenao. Representa o conjunto de frases constitudas por zero ou mais
repeties das frases de p. Alm disso p = (p|).
parnteses: permite alterar a prioridade dos operadores.
Exemplo 2.2 Atendendo s prioridades dos operadores, a expresso regular a|bca sobre o alfabeto {a, b, c} corresponde a a|(b(c(a))).
Alm dos operadores base ainda usual utilizar outros operadores, construdos a partir
dos anteriores, que simplificam a descrio das linguagens atravs de expresses regulares.
28
Uma linguagem regular descrita por uma gramtica regular. Tal como vimos em 1.2.2
uma gramtica regular tem apenas regras da forma A c, A , e A cB ou A Bc,
onde A e B so no terminais ( podendo B = A ) e c um terminal. A gramtica diz-se
linear direita se usar regras da forma A cB ou linear esquerda se usar regras da
forma A Bc, no podendo usar ambas as formas simultaneamente. Alm disso, a
regra A c pode ser deduzida por substituio da regra B numa das outras.
Se L tem uma gramtica regular, ento L uma expresso regular. 1 Se L uma expresso regular, ento L gerado por alguma gramtica linear esquerda e por alguma
gramtica linear direita. 2 Em resumo, gramticas regulares caracterizam expresses
regulares, pois uma linguagem regular se e s se tiver uma gramtica linear esquerda e se e s se tiver uma gramtica linear direita. Ou seja, gramticas regulares e
expresses regulares so representaes equivalentes de linguagens regulares.
29
regular. Existem diversos algoritmos, representados pelas setas da figura seguinte, que
permitem converter expresses regulares de e para diversos tipos de autmatos finitos,
cada um com o seu campo de aplicao.
Thompson
expresses
regulares
H
Y
HH
H
HH Kleene
HH
HH
H
autmato
finito det.
minimizado
Hopcroft
ZZ
}
Z
Z
Z
Z
~
autmato
finito no
determinista
subconjuntos
?
autmato
finito
determinista
gramtica
regular
Nas seces seguintes abordaremos esses autmatos e os algoritmos que permitem obtlos.
Os autmatos finitos so constitudos por um conjunto de estados e por transies dirigidas e etiquetadas entre esses estados. As etiquetas so smbolos da gramtica ou
. Um desses estados designado por inicial, podendo ter um mais estados finais. O
autmato finito pode ser representado graficamente ou por tabela.
30
O reconhecimento de uma frase pode ser efectuado por simulao da rede, comeando
o processamento no estado inicial. Se no fim do processamento nos encontrarmos num
estado final a frase est correcta e faz parte da linguagem em questo. Se o estado
corrente, no fim do processamento, no for um estado final devem-se procurar outros
caminhos.
Exemplo 2.3 A expresso regular (a|b) abb, que designa as frases do alfabeto = { a , b }
que terminam em abb, pode ser representada por
#A a
#
l
U
lA
a
b
b
I3
I1
I0
I2
b
b b
{2}
{3}
2
0
31
q0
r=
- q
qf
0
r=
a
- q
- q
0
f
r=a
como as expresses regulares so fechadas nas operaes base ( ver 1.2.2 ), temos que a
operao de unio de duas expresses regulares r e s tambm a unio das linguagens
descritas por cada uma destas expresses regulares L(r|s) = L(r) L(s),
q1
f1 Q
>
QQ
s
L(r)
- q
f0
0
Z
3
ZZ
~ q
f2
2
L(s)
32
L(r)
- q
f2
2
L(s)
na prtica, o estados f1 e q2 podem ser fundidos num s, poupando um estado e eliminando a transio vazia.
O fecho de Kleene de uma expresso regular s o fecho de Kleene da linguagem descrita
pela expresso regular L(s) = L(s),
?
- q
- q
f0
f1
0
1
L(s)
6
Exemplo 2.5 A expresso regular do exemplo 2.3 representada pelo autmato finito no determinista da figura, construdo pelo algoritmo de thompson,
a2
4 Z
*
?
~
Z
0
1
6
7
8
HH
>
j
6
b3
5
a
?
b
13
12
11
10
9
33
onde a tabela suporta todos os 256 caracteres que podem ser devolvidos pela funo de
leitura getchar() e EOF representa quer o fim da sequncia de entrada, quer o estado
de erro na tabela. A tabela final tem tantos elementos quantos os estados, ou seja o
nmero de linhas da tabela, indicando se cada estado final ou no.
34
A construo de subconjuntos inicia-se no estado inicial e, a partir deste estado, calculase todos os restantes estados que se podem atingir a partir deste estado apenas atravs
de transies vazia. Este conjunto de estados, incluindo o estado inicial, designado
por f echo ({q0 }) e passa a representar o estado inicial do autmato finito determinista, que designaremos por I0 . A partir de cada um dos estados que contituem I0
vamos determinar quais os estados que so atingidos atravs de uma s transio para
cada um dos smbolos do alfabeto . Estes novos conjuntos, designados por move(I0 , a),
onde a , formam o ncleo dos novos estados deterministas. O estado determinista
completamente calculado atravs do f echo (move(I0 , a)), para cada smbolo. No
entanto, se o ncleo de um novo estado igual ao ncleo de um estado j existente, no
necessrio calcular o seu fecho, pois trata-se de uma repetio do estado anterior, que
identificaremos colocando o estado entre parnteses e colocaremos ... para designar os
restantes estados do fecho. O processo termina quando no houver mais estados deterministas por calcular. Os estados deterministas considerados finais so todos aqueles
que contenham pelo menos um estado final do autmato no determinista, que representaremos colocando um quadrado volta do estado.
Para construir os subconjuntos utilizaremos uma tabela com 5 colunas, que representam
respectivamente: o estado determinista a calcular, o smbolo de entrada a considerar, o
ncleo no determinista que obtm, o restante f echo e, finalmente, o novo estado
determinista. Notar que o estado determinista indicado na ltima coluna constitudo
pelos estados no deterministas das duas colunas anteriores.
Exemplo 2.6 A tabela de construo de subconjuntos da expresso regular do exemplo 2.3 representada pelo autmato finito no determinista do exemplo 2.5
5
35
a
b
a
b
a
b
a
b
move
0
4, 9
5
4, 9
5, 11
4, 9
5
4, 9
5, 13
f echo \move
1, 2, 3, 7, 8
1, 2, 3, 6, 7, 8, 10
1, 2, 3, 6, 7, 8
...
1, 2, 3, 6, 7, 8, 12
...
...
...
1, 2, 3, 6, 7, 8
novo estado
I0
I1
I2
(I1 )
I3
(I1 )
(I2 )
(I1 )
I4
a
b
4, 9
5
...
...
(I1 )
(I2 )
estado
entrada
I0
I1
I2
I3
I4
a
0
a
b
3
?/
b
1
a7
o
SS
4
A correspondente tabela de transies pode ser igualmente deduzida da tabela do exemplo 2.6 ou
do diagrama de transio acima,
estado
0
1
2
3
4
a
1
1
1
1
1
b
2
3
2
4
2
36
A representao computacional da tabela directa, contendo apenas duas colunas pois o alfabeto
tem apenas dois elementos.
Exemplo 2.8 A tabela do exemplo 2.7 no tem estado de erro pelo que a partio inicial contm
apenas dois grupos. Para mais, todos os estados transitam para o estado 1 com o smbolo de
entrada a. Desta forma, e neste caso, apenas o smbolo b pode forar a separao dos estados. Dos
quatro estados no terminais, apenas o estado 3 transita com b para um grupo diferente, ou seja
o grupo dos estados finais. Assim, o estado 3 deve ser separado dos restantes passando a haver 3
grupos na nova partio. Agora o estado 1 que transita tambm com b para um grupo distinto
dos outros dois estados, pois na nova partio o estado 3 j est separado.
P0
a,b
P1
0, 1, 2, 3
37
6 7
0, 1, 2
7
6
a,b
?
P2
0, 2
7
a
b
?
1 Z
a
}
Z
6 @@
b
3
@
?
@
Notar que os estados 0, 1, 2, 3 da partio P0 transitam para eles prprio com o smbolo a, mas
divergem quanto s transies com o smbolo b. Conseqeuntemente, na partio P1 o estado 3
separado pois o nico que transita para fora do grupo com o smbolo b. No entanto, os trs
estados restantes ainda no concordam quanto transio com o smbolo b, pois com a sada do
estado 3 do grupo apareceram novas inconsistncias. Desta forma, na partio P2 o estado 1
igualmente isolado, j sendo possvel representar todas as transies do autmato inicial. Assim,
apenas os estados 0 e 2 podem ser agrupados.
Graficamente podemos representar as sucessivas parties, de uma forma mais simples, por uma
rvore,
@
0, 1, 2, 3
@
R4
@
P0
- 0, 1, 2 P
- 0, 2
PP
S
PP
q1
P
S
SS
-3
w 3
-4
P1
-4
P2
38
a
1
1
1
1
b
0
3
4
0
S0
S1
S3
S4
a S1 | b S0
a S1 | b S3
a S1 | b S4
a S1 | b S0 |
O autmato no pode ter entradas no estado inicial, logo caso tais entradas existam
necessrio acrescentar um novo estado inicial com uma transio vazia para o anterior
estado inicial.
0
O algoritmo consiste em introduzir as transies existentes em Rij
= {a|(qi , a) = qj }
0
{|i = j}, ou seja, se i = j ento faz parte de Rij e se existirem transies directas entre
0
os estados qi e qj ento os smbolos dessas transies tambm fazem parte de Rij
.
j=0
39
j=1
a
a|
a
a
a
j=2
b
b|
j=3
j=4
4
Calculando apenas as expresses intermdias necessrias ao clculo de R04
, e simplificando
4
3
3
3
3
3
3
R04 = R04 (R44 ) R44 | R04 = R04 (R44 ), temos,
k
Rij
1
R02
1
R03
1
R04
1
R22
1
R23
1
R24
1
R32
1
R33
1
R34
1
R42
1
R43
1
R44
2
R03
2
R04
2
R33
2
R34
2
R43
2
R44
3
R04
3
R44
4
R04
expresso resultante
a(a | ) | b
a(a | ) b |
a(a | ) |
a(a | ) | (b | )
a(a | ) b |
a(a | ) |
a(a | ) |
a(a | ) b |
a(a | ) | b
a(a | ) | b
a(a | ) b |
a(a | ) |
b(b | ) (a + b) | (a + b)
b(b | ) |
(b | ) (a + b) | (a + b | )
(b | ) | b
b(b | ) (a + b) | (a + b)
b(b | ) |
(b a + b)(a + b | ) b |
(b a + b)(a + b | ) b |
(b (a + b) + b)(b (a + b) + b | )
simplificao
b
a+b
b|
a+b
(a + b) |
b
b
a+b
ba+b
a+b|
b
ba+b
b (a + b) + b
b (a + b) + b |
(b (a + b) + b)+
40
aaa1
2
3
4
r1
a0
6
8 Ze
e
3
Z
~
Z
Z
~
Z
e
5 e
10
r2
e
Q
>
Q
s
b
7
9
41
estado
0
1
2
3
4
a
1
3
E
4
E
b regra
2
E
2
E
2
E
E
1
Notar que os estados 2 e 4 no podem ser agrupados, embora sejam ambos finais e contenham as
mesmas transies, pois pertencem a grupos finais distintos. Relembra-se que os estados podem
ser agrupados mesmo que no tenham transies iguais, basta que tenham transies para estados
que pertenam ao mesmo grupo.
A anlise da frase aa termina no estado 3, depois de ter passado pelo estado 1. Como este estado
no final necessrio procurar o ltimo estado final, neste caso o estado 1. Caso no exista um
estado final no caminho percorrido a sequncia de entrada incorrecta. No caso da frase aa
necessrio recuar um estado, e consequentemente repor o ltimo smbolo de volta na sequncia
a processar, aceitando a expresso regular (a|b). O analisador depois reiniciado no estado 0 e
processa novamente a letra a, que acabou de repor, aceitando mais uma vez a mesma expresso
regular e terminando o processamento por ter atingido o fim da frase.
No caso de um estado final, do autmato determinista, conter mais de um estado final do autmato no determinista, existe um conflito. O conflito resolvido, em geral,
optando por uma das possveis expresses regulares. A soluo mais frequentemente
adoptada pelas ferramentas consiste em considerar prioritria a expresso regular que
surje em primeiro lugar na especificao da gramtica. Contudo, esta soluo obriga a
uma cuidada escrita das expresses regulares, por forma a garantir que todas so devidamente reconhecidas. Notar que os conflitos surjem apenas entre expresses regulares
que possam reconhecer sequncias de igual comprimento.
Exemplo 2.12 Considere-se a linguagem descritas pela unio das seguintes expresses regulares
identificadas por ordem de prioridade decrescente, bem como a tabela de anlise resultante,
r1
r2
r3
aab
aa
(a|b)*
estado
0
1
2
3
4
5
a
1
3
4
4
4
4
b
2
2
2
5
2
2
regra
3
3
3
2,3
3
1,3
da tabela de anlise conclui-se que caso a expresso regular 3 tivesse prioridade sobre as restantes,
estas nunca seriam reconhecidas.
42
Na prtica, na tabela de um linguagem, com um alfabeto constitudos por muitos smbolos distintos, frequente encontrar colunas iguais. Tambm podem existir linhas iguais
se pertencerem a grupos de minimizao distintos, mas tais ocorrncias so escassas.
Notar que a utilizao de digitos decimais em geral indistinto do seu valor, ficando
cada uma das 10 colunas com entradas iguais na tabela. O mesmo pode acontecer com
certas classes de caracteres e operadores ou separadores.
Estes conjuntos de caracteres, cujas entradas na tabela tm os mesmos valores para todos os estados do autmato finito determinista minimizado, so designados por classes
de equivalncia. A compactao da tabela efectuada introduzindo um vector de comprimento igual ao alfabeto da linguagem, onde cada entrada indica a coluna da tabela
a utilizar. Nesta situao podem-se remover todas as colunas duplicadas, apontando
todos os smbolos da mesma classe de equivalncia para a mesma coluna.
Do ponto de vista do analisador lexical desejvel que todos os operadores e separadores constitudos por um nico carcter possam ser reconhecidos por uma s regra, por
exemplo [ + /(); , :], em vez de se reconhecer individualmente cada um. Na grande
maioria dos casos, esta soluo no tem implicaes na restante anlise das linguagens
pois os analisadores sintcticos j reconhecem caracteres individuais. O reconhecimento
individual de cada carcter obriga a considerar expresses regulares distintas, o que
obriga criar mais estados finais distintos.
A tabela de anlise resultante, aps a compresso das colunas iguais, pode ainda ser
mais comprimida atravs de mtodos genricos de compresso de matrizes esparsas.
Estes mtodos, que trataremos mais adiante, permitem tirar partido do facto de certo
valor, por exemplo 0, existir em mais de metade das entradas da tabela. Embora as
tabelas de anlise lexical no apresentem tais caractersticas, ao contrrio das tabelas de
anlise sintctica, pode-se considerar entradas por omisso ( default, em ingls ). Para
tal cria-se uma nova coluna na qual se coloca o valor mais frequente em cada linha.
As ocorrncias desse valor em cada linha so substitudas por uma entrada especial, em
geral codificada com o valor 0, o que significa que quando este valor encontrado devese considerar a entrada por omisso. A tabela resultante passa a conter uma quantidade
significativa de valores por omisso, podendo em casos reais atingir 90% de todas as
entradas da tabela. A tabela pode agora ser compactada por algoritmos genricos de
compresso de matrizes esparsas.
43
state4:
in = *input++;
if (in == a) goto state1;
if (in == b) goto state0;
if (in == 0) return 1; /* s para estados finais */
goto error;
/* termina cada estado */
Outra soluo possvel, sem recurso a saltos, consiste em codificar cada estado como
uma funo, sendo os saltos para as etiquetas subtitudos por chamadas s rotinas que
representam os respectivos estados. No entanto, esta soluo no to eficiente, pois
as chamadas e retorno das rotinas so em geral operaes lentas. Alm disso, utiliza a
pilha do processador para coleccionar os estados por onde vai passando. Assim, a profundidade mxima da pilha limita a maior sequncia a ser reconhecida. Tal limitao
no tem vantagem pois, ao contrrio dos analisadores sintcticos descendentes preditivos que veremos adiante, a informao deixada na pilha no tem interesse prtico
(excepto, eventualmente, para efeitos de backtracking). A partir da gramtica regular do
exemplo 2.9, a regra S4 correspondente ao estado 4 pode ser codificada como
44
2.4 Exerccios
Exerccio 2.1 Considere o diagrama de transio do autmato finito no determinista do exemplo 2.3. Determine, atravs do mtodo dos subconjuntos, a tabela de transio do autmato finito
determinista. Compare o resultado que obteve com a tabela do exemplo 2.9.
Exerccio 2.2 Considere a expresso regular (aa|ab|ba|bb) definida sobre o alfabeto = {a, b}:
Exerccio 2.4 Construa a tabela de transio determinista minimizada das seguintes expresses
regulares:
1. a(a|b) a
2. (a?b)
3. a ba ba
4. (a|b) abb(a|b)
5. a(a|b) + b
6. (aba|bab)
2.4. EXERCCIOS
45
xB
yC|zD|
yC|zD|
yC|zD|
Determine uma expresso regular que defina a linguagem descrita pela tabela
a b
1 2
E 2
1 2
Exerccio 2.9 Apresente a tabela de anlise minimizada e compactada que analisa a linguagem
definida pela expresso regular u(a(e|o)) i, definida sobre o alfabeto = {a, e, i, o, u}.
Captulo 5
Anlise sintctica ascendente por tabela
Um analisador ascendente constro a rvore sintctica das folhas para a raiz. Ao contrrio da anlise descendente, que necessita prever qual a regra a utilizar, a anlise
ascendente atrasa a escolha da regra at ter lido todos os smbolos que constituem a
derivao ( lado direito de uma produo ), mais os smbolos de anteviso necessrios.
A principal deciso de um analisador ascendente consiste em determinar quando uma
sequncia de smbolos corresponde a alguma das regras da gramtica. Esta tarefa no
trivial, pois pode haver mais de uma regra com a mesma derivao e casos em que,
apesar da semelhana, no se tratam de derivaes possveis.
Como os analisadores ascendentes substituem uma derivao de uma regra pelo smbolo no terminal que a origina so globalmente designados por LR(k). A anlise LR(k)
efectuada lendo a sequncia de entrada da esquerda para a direita (Left to right), emparelhando as derivaes das regras da direita para esquerda (Right to left), usando no
mximo k smbolos de anteviso. Estes analisadores so os mais utilizados pois so
menos limitativos que os correspondentes analisadores preditivos descentes LL.
Neste captulo estudaremos em detalhe apenas os analisadores mais simples e menos
exigentes, em termos da dimenso das tabelas necessrias. Contudo, a anlise determinista da grande maioria das linguagens usadas em computao pode ser efectuada com
base em gramticas processveis por analisadores LALR(1). Os analisadores LALR(1)
apresentam tabelas da mesma dimenso das formas mais simples SLR(1) e LR(0), mas
permitem analisar um maior nmero de gramticas. Relembra-se que uma mesma linguagem pode ser descrita por diversas gramticas equivalentes, bastando encontrar
uma dessas gramticas que seja pelo menos LALR(1).
O funcionamento de um analisador ascendente baseia-se em duas operaes fundamentais: o deslocamento (shift) de smbolos da sequncia de entrada para a pilha auxiliar e
a reduo (reduce) dos smbolos de derivao de uma regra ao smbolo no terminal que
57
58
a origina. Inicialmente a pilha comea vazia, sendo deslocados smbolos at ser encontrada uma derivao vlida. O processamento termina quando se atnge uma operao
de aceitao (accept) ou de erro (error).
( A )
a
S
A , a
a gramtica aumentada inclui tambm a regra S S $, passando S a ser o novo smbolo inicial
da gramtica aumentada, ou seja,
S S $
S ( A )
A a
| S
| A , a
59
Exemplo 5.2 Considerando a primeira regra do exemplo 5.1 S ( A ) , so gerados quatro itens, onde o smbolo representa o ponto de processamento da regra no respectivo estado do
autmato no determinista,
S ( A )
S ( A )
S ( A )
S ( A )
Para tornar a leitura mais legvel e compacta representaremos cada estado, do autmato
finito no determinista, pelo seu nmero colocado no ponto de processamento da regra,
ficando a regra do exemplo 5.2 reduzida a S 1 ( 2 A 3 ) 4 .
transies vazias Alm das transies entre os diversos itens de uma regra, etiquetadas pelos smbolos consumidos, necessrio considerar que ao processar um smbolo
no terminal devem ser consideradas todas as regras que esse smbolo pode derivar.
Assim, no item que antecede o processamento de um smbolo no terminal inserem-se
transies vazias para todos os itens iniciais das regras que esse smbolo no terminal
deriva. Na representao que utilizaremos, no etiquetaremos essas transies com o
smbolo , como fizemos nas linguagens regulares, nem representaremos por completo
o arco que une os estados. Desta forma, o item 2 da regra do exemplo 5.2 ser representado por 2 A, significando que no item 2 existem transies vazias para os itens
iniciais das trs regras que o smbolo A deriva. Para posterior referncia, indicaremos
antes de cada regra o seu nmero de ordem, correspondendo r0 ( regra zero ) regra auxiliar da gramtica aumentada. Tal representao pretende apenas simplificar e tornar
mais compacto e legvel o autmato, sendo funcionamente equivalente representao
utilizada nas linguagens regulares.
60
Exemplo 5.3
r1
r2
r3
r4
S
S
A
|
|
S1$
2
( 3 A 4 ) 5
6
a 7
8
S9
10
A 11 , 12 a 13
0
aconselha-se a numerar os itens sequencialmente dentro de cada regra por forma a facilitar a
consistncia das transies, embora apenas se exija que cada item tenha um nmero distinto de
todos os outros do autmato finito no determinista.
Notar que na regra auxiliar da gramtica aumentada existem apenas dois itens, pois no possvel passar alm do fim da sequncia de entrada.
autmato determinista A construo do autmato finito determinista segue exactamente o mesmo processo utilizado nas linguagens regulares. No entanto, como nmero
de smbolos potencialmente grande omitiremos todas as transies que produzam estados deterministas que sejam conjuntos vazios.
Exemplo 5.4
A determinao dos estados do autmato determinista do exemplo 5.3 resume-se a
estado
entrada
I0
S
(
A
a
S
(
)
,
a
I2
I3
I7
move
0
1
3
4, 11
7
9
3
5
12
13
61
construo da tabela de anlise Tal como no caso das linguagens regulares, tambm
a anlise sintctica ascendente utiliza uma tabela de anlise. No entanto, para o seu
processamento necessria uma pilha de dados auxiliar, onde so colocados temporariamente os smbolos at que uma regra seja identificada e a sua derivao substituda
pelo smbolo no terminal que lhe d origem. Neste caso, a tabela inclui cinco tipos de
operaes distintas:
deslocamento (shift) : corresponde a retirar o smbolo da sequncia de entrada e co-loc-lo no topo da pilha, seguido do estado indicado na operao de deslocamento.
Por exemplo s2 ( ou seja, shift 2 ), corresponde a deslocar o smbolo que estiver
cabea da sequncia de entrada e mover para o estado 2 ( do autmato finito
determinista ).
movimento (goto) : corresponde a mover para o estado indicado, colocando-o no topo
da pilha, representado por g2 ( ou seja, goto 2 ).
erro (error) : no representado na tabela de anlise, correspondendo s posies deixadas em branco.
reduo (reduce) : corresponde a substituir os smbolos de derivao de uma regra existente no topo da pilha pelo smbolo no terminal que deriva essa mesma regra.
representado por r2 ( ou seja, reduce 2 ), mas apenas neste caso o nmero 2 no
representa um estado do autmato mas sim o nmero da regra
aceitao (accept) : corresponde reduo da regra auxiliar da gramtica aumentada,
representando o fim do processamente, podendo apenas existir na coluna correspondente ao fim do processamento ( representado por $ ).
A tabela de anlise constituda por todos smbolos terminais, incluindo o fim de processamento $ ( que pode ser lido de um ficheiro ), e todos os smbolos no terminais
da gramtica inicial ( exclui-se a regra auxiliar da gramtica aumentada ). Muita da
literatura separa a tabela de deslocamentos da tabela de movimentos pelo que, embora
utilizaremos uma nica tabela, explicitaremos a sua individualizao por uma dupla
barra.
O autmato finito determinista permite preencher as operaes de deslocamento e movimento da tabela de anlise. O preenchimento idntico, diferindo apenas no facto
de se tratar de um deslocamento para smbolo terminais ( aqueles que podem ser obtidos da sequncia de entrada ) e de um movimento para os smbolos no terminais.
Com base no clculo do autmato finito determinista, e ignorando as duas colunas que
contm os estados no deterministas, ficamos com os valores a preencher
62
Exemplo 5.5
Eliminando os estados do autmato finito no determinista da tabela do exemplo 5.4, o preenchimento das operaes de deslocamento e movimento na tabela de anlise directo. As duas
primeiras colunas designam, por ordem, a linha e a coluna da tabela do autmato finito determinista e a ltima designa o valor a preencher nessa posio.
estado
I0
I2
I3
I7
entrada
novo estado
I0
S I1
( I2
A I3
a I4
S I5
( (I2 )
) I6
, I7
a I8
( a
0 s2
1
2 s2 s4
3
4
5
6
7
s8
8
S A
g1
g5 g3
s6 s7
63
acc (r0)
)
I1
S
A
I0
I2
I3
I7
I4
(
r1
I6
a
I8
r4
r2
I5
r3
Como nos analisadores LR(0) no existem smbolos de anteviso, a reduo ser efectuada para todos os smbolos terminais da linguagem em questo. Excepo feita regra
auxiliar da gramtica aumentada, que apenas pode ser reduzida para o smbolo de fim
de processamento $, pois para qualquer outro smbolo significaria que a sequncia no
estava completamente processada.
Exemplo 5.7 A tabela de anlise LR(0) para a gramtica do exemplo 5.1 fica concluda com
o preenchimento das redues das regras e da operao de aceitao para a regra auxiliar da
gramtica aumentada. Todas as posies deixadas em branco representam situaes de erro.
(
0 s2
1
2 s2
3
4 r2
5 r3
6 r1
7
8 r4
S A
g1
acc
s4
r2
r3
r1
s8
r4
g5 g3
s6
r2
r3
r1
s7
r2 r2
r3 r3
r1 r1
r4 r4 r4
Notar que nenhuma linha da tabela pode ficar totalmente em branco, pois esse estado no seria
necessrio. Da mesma forma, nenhuma coluna da tabela pode ficar totalmente em branco por
esse smbolo nunca seria processado. No caso de um smbolo terminal, significa que esse smbolo
nunca pode ser lido, enquanto no caso de um smbolo no terminal, significa que nenhuma das
regras que ele deriva alguma vez reduzida ( uma vez que aps uma reduo existe sempre um
movimento, excepto para a regra auxiliar ).
64
aco
shift-2
shift-4
reduce-2
goto-3
shift-7
shift-8
reduce-4
goto-3
shift-6
reduce-1
goto-1
accept
65
apaream na pilha pela mesma ordem que so escritas na gramtica, apenas contendo os nmeros
dos estados entre os smbolos.
Aps cada reduo existe sempre uma operao de movimento, utilizando-se os dois elementos
do topo da pilha para determinar as linha e coluna na tabela. Assim, no quarto passo, o topo da
pilha indica linha 2 e coluna A, ou seja, g3 ( goto-3 ).
( a
0 s2
1
2 s2 s4
3
4
5
6
7
s8
8
S A
g1
acc
g5 g3
s6
r2
r3
r1
s7
r2
r3
r1 r1
r4 r4
Notar que a anlise da tabela gerada pelo mtodo SLR(1) igual anlise da tabela
LR(0), apenas em caso de reduo com smbolo de anteviso que no pertena ao conjunto FOLLOW imediatamente gerado um erro e parado o processamento. Alm
disso, caso existam operaes de deslocamento nessas posies, deixa de haver conflitos, sendo essas gramticas SLR(1) mas no LR(0).
66
S
|
|
A
A b b
a a b
b A a
a
r1
r2
r3
r4
S
S
|
|
A
S1$
2
A 3 b 4 b 5
6 a 7 a 8 b 9
10
b 11 A 12 a 13
14
a 15
0
entrada
I0
S
A
a
b
b
a
A
a
b
b
a
I2
I3
I4
I5
I6
I7
novo estado
I0
I1
I2
I3
I4
I5
I6
I7
I8
I9
I10
I11
FOLLOW(S) =
FOLLOW(A) =
{$}
{ a , b }
67
0
1
2
3
4
5
6
7
8
9
10
11
a
s3
b
s4
S A
g1 g2
acc
s6/r4
s8
s5
r4
g7
s9
s10
s11
r4
r4
r1
r2
r3
68
r0
r1
r2
S
|
r3
r4
S1$
A 3 b 4 b 5
6
a 7 a 8 b 9
2
b 11
14
a 15
10
A 12 a 13
o primeiro passo no clculo do autmato determinista tem presente que o estado 0 transporta o
smbolo de anteviso $ para os estados 2, 6, 10, mas que o estado 2 apenas transporta o smbolo
de anteviso b para o estado 14, pois quando a regra A a reduzir s poder ter a seguir o
smbolo b ,
estado
entrada
no segundo passo todos os smbolos de anteviso so transportados para o respectivo estado seguinte da regra, que de acordo com a sequncia de numerao utilizada corresponde tambm ao
nmero seguinte. Apenas a transio vazia do estado 11 para o estado 14 necessita calcular novos
smbolos de anteviso,
estado
I0
entrada
move
0$
S 1$
A 3$
a 7$ , 15 b
b 11$
entrada
I0
S
A
a
b
b
a
A
a
b
b
a
I2
I3
I4
I5
I6
I7
move
0$
1$
3$
7$ , 15 b
11$
4$
8$
12$
15 a
5$
9$
13$
69
Notar que agora o estado 15 aparece com o smbolo de anteviso b em I3 , mas com a em I8 .
Desta forma, a reduo da regra 4 apenas colocada na coluna b para o estado I3 e apenas na
coluna a para o estado I8 . Podemos verificar, atravs de uma observao cuidada da gramtica do exemplo que este efectivamente o caso, ficando a tabela de anlise gerada pelo mtodo
LALR(1)
0
1
2
3
4
5
6
7
8
9
10
11
a
s3
b
s4
S
g1
A
g2
acc
s6
s8
s5
r4
g7
s9
s10
s11
r4
r1
r2
r3
Quando os smbolos de anteviso no podem ser identificados no autmato no determinista, quando o no terminal o ltimo smbolo da regra, utilizaremos o smbolo
para indicar o transporte dos smbolos de anteviso anteriores para os estados atingidos
r1
r2
r3
S
S
|
|
S1$
2 i 3
S4
0
i 6
10 x 11
S 7 e 8 S 9
70
estado entrada
I0
I0
S
i
x
S
i
move
0$
1$
3$ , 6$
11$
4$ , 7$
3$ , 6$
neste ponto surje uma nova ocorrncia do estado I2 = {3, 6, 2, 5, 10} mas com smbolos de
anteviso distintos nos estados 2, 5, 10. Para que os smbolos de anteviso das duas ocorrncias
fiquem coerentes necessrio que esses trs estados passem a ter ambos os smbolos de anteviso,
passando I2 = {3$ , 6$ , 2$, e , 5$, e , 10$, e } em ambas as ocorrncias. No entanto, os estados I3
e I4 j foram entretanto calculados com base nos anteriores smbolos de anteviso de I2 , embora
haja situaes em os novos smbolos de anteviso de I2 no afectam I3 e I4 este no o caso.
Assim, o processo deve ser repetido a partir da primeira ocorrncia de I2 , mas agora com os novos
smbolos de anteviso
estado
entrada
I0
S
i
x
S
i
I0
move
0$
1$
3$ , 6$
11$, e
4$, e , 7$, e
3$, e , 6$, e
f echo \move
2$ , 5$ , 10$
novo estado
I0
I1
I2
I3
I4
(I2 )
notar que mais uma vez a segunda ocorrncia de I2 ficou com smbolos de anteviso distintos da
primeira ocorrncia, mas desta vez nos estados 3 e 6. O processo repete-se, mas desta vez sem
consequncias para os estados entretanto j re-calculados, ficando a tabela completa
entrada
I0
S
i
x
S
i
x
e
S
i
x
I0
I4
I5
71
move
0$
1$
3$, e , 6$, e
11$, e
4$, e , 7$, e
3$, e , 6$, e
11$, e
8$, e , 7$, e
9$, e
3$, e , 6$, e
11$, e
f echo \move
2$ , 5$ , 10$
novo estado
I0
I1
I2
I3
I4
(I2 )
(I3 )
I5
I6
(I2 )
(I3 )
i
0 s2
1
2 s2
3
4
5 s2
6
x
s3
S
g1
acc
s3
r3
s5/r1
g4
r3
r1
s3
r2
g6
r2
72
gramticas, existam nada me garante que a minha anlise da linguagem produza uma
dessas gramticas.
Nesta seco tentaremos ver alguns procedimentos simples que permitem modificar a
gramtica por forma a evitar conflitos desnecessrios e que resultam, em geral, de vcios
do utilizador ou de descries que dirigem o utilizador para solues menos conflituosas.
Os conflitos tm sempre origem em redues, sendo estas efectuadas quando se atnge o
ltimo estado de uma regra, para certos smbolos de anteviso. Se o estado determinista
contiver outros estados no deterministas em posio de reduo ou deslocamento, para
o mesmo smbolo de anteviso, ento esse estado tem um conflito. Desta forma a primeira regra para evitar conflitos criar regras compridas, ou seja com muitos smbolos,
face a muitas regras curtas, pois cada regra usada necessita ser reduzida. Existe ainda
uma vantagem no desempenho do analisador j que cada regra usada consome dois
passos de processamento, um para a reduo e outro para o movimento, e provavelmente necessitar de mais estados na tabela de anlise. Alm disso cada novo smbolo
no terminal acrescenta mais uma coluna tabela.
x y z
A y
A z
x
onde a sequncia xy pode ser reconhecida pela primeira regra ou pela segunda regra seguida da
quarta. Aps a leitura do carcter x, quando o carcter de anteviso y, a primeira regra pode
deslocar-se mais um smbolo, mas a quarta regra pode reduzir para processar o y na segunda
regra.
A reduo do nmero de regras, nomeadamente com a aplicao da propriedade distributiva, enumera as diversas solues e elimina as redues problemticas.
A utilizao de regras vazias, por transportarem todos os smbolos de anteviso, est na
origem de muitos conflitos deslocamento-reduo. Estas regras tm em geral origem no
73
facto de certa entidade poder ocorrer zero ou mais vezes. No entanto, tal facto pode ser
descrito com duas regras idnticas: uma das regras contm a entidade como obrigatria
e a outra no contm a entidade. As duas regras representam uma ou mais ocorrncias
da entidade e a sua no ocrrncia, ou seja, no seu conjunto zero ou mais ocorrncias da
entidade.
Exemplo 5.14 Na linguagem C um bloco pode conter zero ou mais declaraes seguida de zero
ou mais instrues, qualquer delas terminada em ;. Assim, em vez de indicar
bloco { decl_opt instr_opt }
decl_opt
| decl
instr_opt
| instr
enumeram-se a quatro possibilidades, ou seja,
bloco
|
|
|
{ decl instr }
{ decl }
{ instr }
{ }
genrica
anterior
if expr then genrica else genrica
outras
if expr then genrica else anterior
if expr then instr
74
Finalmente, caso no se consiga encontrar uma soluo vivel, pode-se sempre manter
o conflito e assumir que o deslocamento a soluo adoptada. No entanto, isto significa que tabela de anlise gerada no corresponde gramtica inicial, atendendo ao
mtodo de gerao utilizado. Para evitar estar dependente do comportamento da ferramenta, o utilizador pode indicar prioridades e associatividades das regras como forma
de controlar o processamento de gramticas ambguas ( ver 5.4 ). No caso de conflitos
reduo-reduo esta perspectiva j no se aplica.
A
B
x
y
x
z
onde aps a leitura do smbolo x quer a regra A x como a regra B x podem podem ser
reduzidas para o smbolo de anteviso $.
Uma soluo consiste em considerar que ambas as ocorrncias da parte comum da regra podem ser tratadas sintacticamente como a mesma, sendo quaisquer distines ser
efectuadas semnticamente. Ou seja, embora fosse desejvel separar o processamento,
as tcnicas existentes no permitem faz-lo atravs de regras sintcticas. Assim, criase uma nica regra, com a parte comum, e trata-se as possveis diferenas atravs de
atributos.
Exemplo 5.17 Na gramtica do exemplo 5.16 transporta-se a parte comum das regras em conflito para a regra comum que as deriva,
S
|
|
A
B
A
B
x
y
z
75
A
B
w
y
x
z
76
Quando a gramtica produzida contm conflitos, mas o utilizador sabe qual o comportamento que pretende em cada conflito, deve indic-lo explcitamente. Tal evita dvidas
futuras e documenta claramente o comportamento desejado.
A manuteno de conflitos deslocamento-reduo traduz, para ferramentas como o gerador yacc, na opo pelo deslocamento. Embora esta possa ser, de uma forma geral,
a opo mais desejada, tal no necessariamente o caso. A utilizao de prioridades e
associatividades nas regras permite remover conflitos deslocamento-reduo, optando
explicitamente pelo deslocamento ou pela reduo. Claro que a utilizao destas tcnicas de forma cega, embora removendo os conflitos, pode traduzir-se numa gramtica
completamente distinta da especificada e, por vezes, no reflectindo a linguagem que
pretende efectivamente processar. Desta forma, a utilizao de prioridades e associatividades para eliminar conflitos deve ser utilizada conscientemente.
A determinao de prioridades e associatividades num analisador sintctico ascendente
est associada a regras e a operadores. Embora algumas ferramentas, como o gerador
yacc, permitam indicar a prioridade e associatividade de um operador, na realidade o
utilizador est a indicar a prioridade e associatividade todas as regras que usam esse
smbolo. Notar que quando se pretende atribuir prioridades distintas regras que usam
o mesmo operador, como o operador - unrio e binrio, torna-se necessrio identificar
a regra atravs de uma etiqueta nica.
Num conflito deslocamento-reduo, ao optar pela reduo estamos a obrigar a aplicar
imediatamente a regra, antes de ver o que se segue, ou seja estamos a ser associativos
esquerda. Da mesma forma, ao optar pelo deslocamento vamos acumulando na pilha
as diversas ocorrncias, sendo posteriormente obrigados a reduzir as regras pela ordem
inversa, pois trata-se de uma pilha. Finalmente, caso uma regra no seja associativa,
no podemos permitir nem a reduo nem o deslocamente, limitando-nos a remover
ambos e deixar em seu lugar uma situao de erro.
Exemplo 5.19 Considermos um exemplo apenas com o operador subtrao. Este operador tem a
vantagem de produzir resultados distintos consoante usado associativo esquerda ou direita,
mas do ponto de vista gramatical o problema subsiste para operadores comutativos, como por
exemplo a soma.
E
|
E - E
id
0
1 s3
2 r2
3
4 s3/r1
id
s2
77
E
g1
acc
r2
s2
g4
r1
Exemplo 5.20 Consideremos uma gramtica, deliberandamente ambgua, mas onde a linguagem a processar apresenta, por ordem crescente de prioridades, operaes de soma, multiplicao,
potncia, e valor simtrico. Do ponto de vista de associatividade pretende-se que quer a soma
como a multiplicao sejam associativas esquerda, a potncia pretende-se associativa direita
e, finalmente, o valor simtrico no seja associativo.
E
|
|
|
|
E + E
E * E
E E
- E
id
78
0
1
2
3
4
5
6
7
8
9
10
s4
s5
s6
s2
r5
s5/r4
s5/r1
s5/r2
s5/r3
s3
r5
E
g1
g7
r5
s2
s2
s2
s4/r4
s4/r1
s4/r2
s4/r3
id
s3
acc
s2
r5
s3
s3
s3
s6/r4
s6/r1
s6/r2
s6/r3
g8
g9
g10
r4
r1
r2
r3
+
r4
r1
r2
r3
7
8
9
10
r4
s5
r2
r3
r4
s6 r1
s6 r2
s6 r3
i e
0 s2
1
2 s2
3
r3
4
s5
5 s2
r2
6
x
s3
S
g1
acc
s3
g4
r3
r1
s3
g6
r2
Embora seja esse o comportamento por omisso das ferramentas, a indicao explcita das prioridades evita mensagens desnecessrias e afirma inequivocamente a opo do utilizador.
79
Finalmente convm referir que a atribuio de prioridades e associatividades a gramticas ambguas apresenta ganhos significativos na dimenso das tabelas de anlise e
no nmero de passos de processamento, quando comparado com gramticas no ambguas que resolvem explicitam essas prioridades e associatividades gramaticalmente.
De facto, numa linguagem com 10 nveis de prioridade tm de existir 9 regras adicionais para transitar entre prioridades, na presena de smbolos de anteviso associados
a regras de menor prioridade. Tais regras aumentam, necessariamente, a dimenso das
tabelas. Por outro lado, cada vez que o operador menos prioritrio utilizado, as 9 regras de transio tm de ser reduzidas, e aps cada reduo ainda necessrio efectuar
a movimentao para o novo estado. Esta situao mais frequente que se pode supor
e justifica tcnicas especfcas para obviar esta sobrecarga ( ver 5.5.3 ).
E E _ E
E E
E _ E
( E )
id
80
0
1
2
3
4
5
6
7
8
9
10
11
s4
s5
(
s2
r5
r5
E
g1
s5
s10/r2
s5/r3
r4
g6
r5
s3
s3
s9
r2
r3
r4
s2
s4/r1/r3
s3
s2
s2
s4
s4/r2
s4/r3
r4
id
s3
acc
s2
r5
s5/r1/r3
g7
g8
r2
r3
r4
s3
r1/r3
g11
r1/r3
81
82
Por exemplo em vez de g7 ser colocado r4 assumindo que o estado 7 apenas contm
redues da regra 4.
As operaes de deslocamento so na realidade duas operaes em sequncia, um deslocamento do smbolo cabea da sequncia de entrada para o topo da pilha, seguido de
um movimento para o estado indicado. Se for criada uma nova operao que mantm
o deslocamento mas substitui o movimento pela reduo, o estado contendo a reduo
unitria pode ser removido da tabela. Assim, na tabela uma operao designada por
L4 representa um deslocamento seguido da reduo da regra 4 e substitui um deslocamento para estado que continha a reduo unitria, por exemplo s7.
Exemplo 5.23 A tabela do exemplo 5.7 foi criada pelo mtodo LR(0) pelo que as redues j
esto propagadas para todos os smbolos de anteviso. Neste caso so eliminados 4 estados e
substitudos os saltos, resultando uma tabela com quase metade da dimenso original,
( a
0 s2
1
2 s2 L2
3
7
L4
S A
g1
acc
r3
L1
g3
s7
os nmeros dos estados originais foi mantido para referncia com o exemplo 5.7.
Exemplo 5.24 No exemplo 5.11 apenas os 4 ltimos estados podem ser eliminados, depois de
propagadas as redues, j que o estado 3 inclui um deslocamento alm de uma reduo
a
0 s3
1
2
3 s6
4 L4
5
6
7 L3
b
s4
S
g1
A
g2
acc
s5
r4
g7
L1
L2
83
a
0 s3
1
2
3 s6
4 L4
5
6
7 L3
b
s4
def
S
g1
A
g2
acc
s5
r4
g7
L1
L2
Notar que neste exemplo, em que existe uma nica reduo quase unitria, limitamo-nos a deslocar a reduo de uma coluna para outra, embora a tabela passe a ter mais uma coluna. No
entanto, como as operaes por omisso so quase todas situaes de erro, e consequentemente
representadas por posies vazias, a tabela igualmente esparsa. De facto, utilizando o mtodo
84
Regras unitrias, cuja derivao tem um nico smbolo, esto frequentemente associadas a restries de prioridade entre operadores. Atendendo a que uma linguagem de
programao pode ter mais de 10 nveis de prioridade, podemos ter sequncias de 11
redues consecutivas e respectivos movimentos.
A compactao de redues unitrias pretende, com base no smbolo de anteviso reduzir directamente para a regra associada a esse smbolo, poupando todas as redues
intermdias. De um ponto de vista prtico, isto s pode ser efectuado se no houver
aces semnticas associadas a essas regras intermdias, pois seriam ignoradas. Tal ,
geralmente, o caso.
Note-se que este expediente no diminui a dimenso das tabelas, muito pelo contrrio. De facto, cada estado em vez de conter redues de uma s regra, possibilitando
a propagao de redues unitrias ou quase unitrias, vamos passar a ter diversas redues distintas, consoante o smbolo de anteviso. A vantagem reside no facto de o
processamento ser mais eficiente, pois efectuado em menos passos.
Uma soluo mais compacta e igualmente eficiente, consiste em especificar uma gramtica ambgua e atribuir prioridades e associatividades aos operadores ( ver 5.4.1 ). Este
expediente reduz efectivamente o nmero de regras e consequentemente o nmero de
estados da tabela de anlise, mas a sua especificao depende da ferramenta utilizada e
das suas capacidades.
85
( A )
a
S
A , S
error
( a
0 s2
1
2 s2 s4
3
4
5
6
7
8 s2
9
error
S
g1
g5
g3
acc
s6
s7
r2
r3
r5
r1
s8
r2
r3
r5
r1
r1
g9
r4 r4
86
aco
shift-2
shift-4
error
discard-4
shift-6
discard-a
reduce-5
goto-3
shift-7
reduce-1
goto-1
accept
(
0 s2
1
2 s2
3
8 s2
error
def
S A
g1
acc
L2
L5
L1
r3
g3
s8
r4
87
aco
shift-2
shift-2
shift-4
reduce-2
goto-3
shift-7
reduce-1
goto-5
error
discard-5
shift-6
error
discard-6
shift-6
( A )
error )
a
S
A , S
A colocao de regras de erro deve ser cuidada pois, em primeiro lugar a introduo
de novas regras pode sempre gerar conflitos, alm disso o excesso destas regras pode
dificultar a determinao de qual a regra que ser activada em cada situao, a menos
que se tenha presente o contedo da pilha do analisador. Assim, nas linguagens de
88
89
Exemplo 5.28 Como no mtodo LR(1) o smbolo de anteviso apenas utilizado no ltimo
estado, este ser colocado aps os restantes smbolos da regra. Alis, este j era o expediente para
introduzir o smbolo de fim de sequncia utilizado na regra auxiliar da gramtica aumentada.
90
r0
r1
r2
S1$
c , d
c 6
A3 A4$
c
A 7 c
c 9 A 10 d
$
11
c 12 A 13 $
14
d 15 c
16
d 17 d
18
d 19 $
8
r3
estado
entrada
I0
S
A
c
d
A
c
d
A
c
A
c
d
I2
I3
I6
move
0
1
3
6, 9
15, 17
4
12
19
7, 10
6, 9
13
12
19
a tabela de anlise construda da mesma forma utilizada nos mtodos anteriores, tendo o cuidado
de utilizar apenas o smbolo de anteviso associado ao estado a reduzir. Por exemplo, o estado 10
reduz apenas para o smbolo d.
91
c
0 s3
1
2 s6
3 s3
4 r3
5
6 s6
7
8 r2
9
d
s4
S A
g1 g2
acc
s7
g5
g8
r3
r1
s7
g9
r3
r2
r2
A tabela resultante, com 10 estados, apenas 43% maior que utilizando os mtodos anteriores,
mas a gramtica muito pequena e usa muito poucos smbolos de anteviso. De facto esta
gramtica tambm LALR(1) e at LR(0), embora a tabela LR(1) resultante seja distinta.
O mtodo LR(1) produz tabelas de grandes dimenses para gramticas de linguagens
usadas na prtica. Por exemplo, linguagens como a linguagem C necessitam de pouco
mais de 200 regras ( correspondendo a quase 400 estados pelo mtodo LALR(1) ), enquanto a linguagem Java requer quase 400 regras e a linguagem C++ mais de 600 regras.
Se atendermos a que o mtodo LR(1), gera cerca de dez vezes mais estados que o correspondente LALR(1), a sua utilizao torna-se bastante limitativa. Na realidade, a maioria
das ferramentas de software existentes geram analisadores ascendentes LALR(1).
92
c
d
0 s3,6 s4,7
1
2 s3,6 s4,7
3,6 s3,6
r3
4,7 r3
5
8,9 r2
r2
S
g1
A
g2
acc
g5
g8,9
r3
r1
r2
indicamos os estados com os seus nmeros originais para facilitar a compreenso do processo de
agrupamento, mas atravs da renumerao dos estados obtemos uma tabela igual gerada pelo
mtodo LALR(1), pois a gramtica LALR(1).
O processo de agrupamento pesado, pois tem de ser construdo um autmato no determinista LR(1), efectuada a sua converso em determinista, o que s por si pesado,
como ainda necessrio descobrir quais os estados a grupar. Identificar quais os estados a agrupar computacionalmente pesado, pois temos de comparar cada estado com
todos os restantes, mesmo os j entretanto agrupados. Quando realizado mentalmente
o processo simplifica-se pois podemos identificar os itens equivalentes e testar apenas
os estados deterministas que contm pelo menos um desses estados como possveis
candidatos.
93
94
S
|
X
Y
A x
B c
a c
a
X a b
Y a c
a, c
0 s4
1
2
3
4
5
6
7
0
1
2
3
4
5
6
7
a, b
r3
c , x
x ,$
c , $ $, $
S A
g1 g2
B
g3
acc
s5
s6
s7
r4
r1
r2
r3
b ,$
a, c
c , $ $, $
r4
acc
S X Y
g1 g2 g3
s4
s5
s6
s7
r1
r2
95
lista term
| term
lista
term lista
| term
lista
term1 lista
term1 term2 lista
term1 term2 term3 lista
term1 term2 term3 term4 lista
term1 term2 term3 term4 term5
Um analisador ascendente constroi a estas sequncias por ordem inversa, de baixo para
cima.
recurso esquerda Ao recorrer recurso do lado esquerdo o analisador desloca o
primeiro terminal term1 para a pilha e de seguida aplica a segunda regra, reduzindo-o a
lista. Seguidamente, desloca term2 e, novamente, reduz o conjunto a lista. Desta forma,
em mdia.
a pilha contm no mximo dois elementos e 10
6
96
lista term
|
lista
criar a lista
adicionar ao fim da lista
verificar se uma lista vazia
Num analisador ascendente a primeira reduo efectuada para a derivao vazia (),
que cria a lista. Cada novo elemento adicionado a essa lista pela ordem inversa, permitindo o seu posterior processamento pela ordem correcta, a que corresponde a associatividade direita. No fim, como com a gramtica alterada passmos a permitir
listas vazia, necessitamos de verificar se a lista no contm elementos e, caso seja o caso,
reportar um erro.
Notar que o processo no estritamente gramatical, requerendo que as aces associadas a cada regra colaborem no processo. O mesmo processo tambm pode ser utilizado
para permitir associatividade esquerda com recursividade direita. No entanto, muitos compiladores no recorrem a este processo, apresentando um limite de recurso no
processamento de operadores associativos direita. Embora a maioria das linguagens
no tenha muitos operadores associativos direita, um teste pode ser realizado repetindo sucessivamente, em geral 5000 vezes suficiente, tal operador. Por exemplo, na
linguagem C pode-se repetir sucessivas atribuies de uma varivel a ela prpria.
5.9. EXERCCIOS
97
5.9 Exerccios
Exerccio 5.1 Desconhecendo a gramtica e o mtodo ascendente utilizado para gerar a tabela
seguinte, justifique se a gramtica LR(1), LALR(1), SLR(1) ou LR(0):
0
1
2
3
4
5
a
s3
S A B
g1 g2
acc
s5
r2
g4
r1
r3
98
MN
a
M a
b M c
d c
b d a
a
[ E ; L ]
id
E
E ; L
y|z
BAx|ABzy|By|x
5.9. EXERCCIOS
99
3. Apresente uma tabela com o contedo da pilha, a entrada e a aco realizada em cada
passo da anlise, quando a sequncia de entrada : x y z x . Indique em quantos passos
processada a sequncia indicada.
(em caso de conflito assuma o mesmo comportamento da ferramenta YACC)
Exerccio 5.7 Considere a gramtica,
S
|
|
L
|
a
( L )
( error )
S
L , S
Construa uma tabela de anlise, pelo mtodo SLR(1), e apresente os passos necessrios para a
anlise das sequncias:
1. (a, (a, , a, ), (a))
2. (a, , (a), a)
3. (a, a, (a, (a, a)
Exerccio 5.8 Construa a tabela de anlise para a gramtica seguinte, resolvendo os conflitos
que encontrar por forma a que as operaes tenham a precedncia usual,
E
|
|
|
while E do E
id := E
E + E
id
Exerccio 5.9 Considere a gramtica onde se pretende que os operadores tenham a prioridade e
associatividade usado na linguagem C.
E
|
|
|
bin
una
E bin E
una E
( E )
id
= | + | - | * | / | %
- | *
100
2. Apresente a tabela de anlise de uma gramtica ambgua equivalente, mas que j permita
definir as prioridades e associatidades por resoluo dos conflitos criados.
3. Apresente a tabela de anlise de uma gramtica no ambgua equivalente, onde as prioridades e associatidades foram resolvidas gramaticalmente
4. Indique em quantos passos analisada a sequncia x = a + b (c d), por ambas as
tabelas de anlise. Compare as duas solues quanto dimenso da tabela e nmero de
passos necessrios.
5. Construa a tabela de anlise para a gramtica no ambgua aplicando as redues unitrias existentes e compare o nmero de passos agora necessrios para processar a mesma
sequncia.