Autˆ
omatos de Pilha
Apesar das in´umeras aplica¸c˜oes dos formalismos associados `as linguagens regulares, existem aplica¸c˜oes que requerem linguagens mais sofisticadas e que, portanto, envolvem o uso de formalismos mais sofisticados. Por exemplo, s˜ao comuns as aplica¸c˜oes em que se deve escrever express˜oes aritm´eticas. As linguagens das express˜oes aritm´eticas normalmente contˆem todas as palavras da forma:
(nx0+x1)+x2)· · · +xn)
em que n ≥ 0, cada xi´e uma subexpress˜ao, e o n´umero de (s ´e igual ao de )s.
Aplicando-se o lema do bombeamento, vˆe-Aplicando-se que tais linguagens n˜ao s˜ao regulares: tomando-Aplicando-se z = (kx0+x1)+x2)· · · +xk), em que k ´e a constante referida no lema, vˆe-se que para
quaisquer u, v e w tais que z = uvw, |uv| ≤ k e v 6= λ, uv2w = (k+|v|x0+x1)+x2)· · · +xk),
que tem mais (s do que )s.
Intuitivamente, um AF n˜ao pode reconhecer a linguagem descrita porque n˜ao tem uma mem´oria poderosa o suficiente para “lembrar” que leu n ocorrˆencias de certo s´ımbolo, para n arbitr´ario. A ´unica maneira de ler uma quantidade arbitr´aria de determinado s´ımbolo, em um AF, ´e por meio de um ciclo. E, nesse caso, n˜ao h´a como contar o n´umero de s´ımbolos lidos.
Neste cap´ıtulo, ser´a apresentada uma extens˜ao dos AFs, os denominados autˆomatos de pilha,1 de grande importˆancia, visto que constituem uma base para a obten¸c˜ao de reconhecedores para muitas linguagens que ocorrem na pr´atica. Em particular, alguns compiladores de linguagens de programa¸c˜ao utilizam alguma variante de autˆomato de pilha na fase de an´alise sint´atica.
Ao contr´ario dos AFs, a vers˜ao n˜ao determin´ıstica desse tipo de autˆomato tem uma abrangˆencia de reconhecimento maior que a determin´ıstica. No entanto, as linguagens que podem ser reconhecidas por autˆomatos de pilha determin´ısticos s˜ao especialmente
1
Em inglˆes, pushdown automata.
a1 a2 · · · ai · · · an i fita de leitura apenas, unidirecional
❄
controle
+
δ
e registrador com estado atual
b1 b2 .. . bn topo da pilha pilha
Figura 3.1 Arquitetura de um APD.
importantes, j´a que admitem reconhecedores eficientes. Algumas constru¸c˜oes que ocor-rem em linguagens que podem ser reconhecidas por autˆomatos de pilha n˜ao deter-min´ısticos, mas que n˜ao podem ocorrer em linguagens que possam ser reconhecidas por autˆomatos de pilha determin´ısticos, alertam para o fato de que se est´a transitando do campo da eficiˆencia de reconhecimento para o da ineficiˆencia.
Antes de apresentar as vers˜oes determin´ıstica e n˜ao determin´ıstica de autˆomatos de pilha nas Se¸c˜oes 3.2 e 3.3, ser´a vista uma introdu¸c˜ao informal de autˆomato de pilha determin´ıstico na Se¸c˜ao 3.1. Depois, na Se¸c˜ao 3.4, ser˜ao estudadas as gram´aticas livres do contexto, que s˜ao um formalismo de grande utilidade pr´atica para a especifica¸c˜ao de linguagens reconhec´ıveis por autˆomatos de pilha. Para finalizar, algumas propriedades importantes dessa classe de linguagens ser˜ao abordadas na Se¸c˜ao 3.5.
3.1
Uma Introdu¸
c˜
ao Informal
Um autˆomato de pilha determnin´ıstico (APD) pode ser visto como uma m´aquina similar `
aquela ilustrada na Figura 2.47, p´agina 120, que contenha adicionalmente uma pilha, como mostrado na Figura 3.1. Como a fita, a pilha ´e dividida em c´elulas que comportam apenas um s´ımbolo cada uma, mas o cabe¸cote de leitura da pilha s´o se posiciona na c´elula do topo da pilha. No in´ıcio, o registrador cont´em o estado inicial do APD, a fita recebe a palavra de entrada a partir da sua primeira c´elula, o cabe¸cote da fita ´e posicionado na primeira c´elula da fita e a pilha est´a vazia.
Agora, al´em do alfabeto da fita haver´a o alfabeto da pilha (n˜ao necessariamente disjunto do da fita). E embora a ocorrˆencia de uma transi¸c˜ao a partir de um estado possa depender do s´ımbolo de entrada e do s´ımbolo no topo da pilha, ser´a permitido
ap fp (, λ/X
a, λ/λ
), X/λ
+, λ/λ; ∗, λ/λ
Figura 3.2 Reconhecendo express˜oes aritm´eticas simples.
tamb´em que ela dependa apenas do s´ımbolo de entrada (ignorando o que est´a no topo da pilha) ou apenas do s´ımbolo no topo da pilha (ignorando o s´ımbolo de entrada). A palavra vazia, λ, ser´a usada nestes ´ultimos dois casos para indicar a inten¸c˜ao de ignorar a entrada ou a pilha.
Suponha um APD com conjunto de estados E, alfabeto de entrada (alfabeto da fita) Σ e alfabeto da pilha Γ. Em uma computa¸c˜ao, ao transitar de um estado e para um estado e′, caso o s´ımbolo de entrada seja a ∈ Σλ (se a = λ, nada ´e lido) e o s´ımbolo
do topo da pilha seja b ∈ Γλ (se b = λ, o s´ımbolo do topo da pilha ´e ignorado), o APD
poder´a empilhar zero ou mais s´ımbolos (representados por uma palavra z ∈ Γ∗) no lugar
de b. Tendo isso em mente, cada transi¸c˜ao do APD ser´a da forma δ(e, a, b) = [e′, z], em que e, e′ ∈ E, a ∈ Σλ, b ∈ Γλ e z ∈ Γ∗. Essa transi¸c˜ao ser´a dita uma transi¸c˜ao de
e para e′ sob a desempilhando b e empilhando z, sendo representada em um diagrama
de estados da seguinte forma:
e a, b/z e′
significando, no caso em que a 6= λ, b 6= λ e z 6= λ, que “estando no estado e, se o pr´oximo s´ımbolo de entrada for a e o s´ımbolo no topo da pilha for b, h´a uma transi¸c˜ao para o estado e′, b ´e desempilhado e z, empilhado (o s´ımbolo mais `a esquerda em z, no topo)”. Se a = λ, n˜ao ´e consumido o s´ımbolo de entrada. Se b = λ, a transi¸c˜ao acontece sem consulta `a pilha e nada ´e desempilhado. E se z = λ, nada ´e empilhado. Se z = a0a1. . . an, ent˜ao os s´ımbolos s˜ao empilhados na ordem an, an−1, . . . , a0.
Um APD simples que reconhece certo tipo de express˜ao aritm´etica ´e apresentado a seguir.
Exemplo 70 Seja o conjunto EA das express˜oes aritm´eticas com parˆenteses e as opera¸c˜oes de soma (+) e multiplica¸c˜ao (*), definido recursivamente por:
a) a∈ EA;
b) se x, y ∈ EA, ent˜ao (x) ∈ EA, x+y ∈ EA e x∗y ∈ EA.
O s´ımbolo a pode ser imaginado como representando express˜oes mais b´asicas, como n´umeros inteiros e/ou reais, identificadores de vari´aveis etc. O reconhecimento de tais express˜oes b´asicas n˜ao oferece nenhum problema, podendo ser feito mediante um AF. A Figura 3.2 apresenta um diagrama de estados para um APD que reconhece EA. Observe que o conjunto de estados ´e E = {ap, fp}, o alfabeto de entrada ´e Σ = {a, (, ), +, ∗}, e
o da pilha, Γ = {X}. O estado inicial ´e ap e o conjunto de estados finais, {fp}. Existem cinco transi¸c˜oes:
1. δ(ap, (, λ) = [ap, X]; 2. δ(ap, a, λ) = [fp, λ]; 3. δ(fp, ), X) = [fp, λ]; 4. δ(fp, +, λ) = [ap, λ]; 5. δ(fp, ∗, λ) = [ap, λ].
As transi¸c˜oes est˜ao numeradas para referˆencia futura. Os detalhes de funcionamento desse APD ser˜ao elucidados do decorrer desta se¸c˜ao, `a medida que os conceitos ne-cess´arios forem sendo introduzidos.
Uma pilha de s´ımbolos de um alfabeto Γ ser´a representada por meio de uma palavra de Γ∗. A conven¸c˜ao adotada ´e que o s´ımbolo mais a esquerda est´a no topo. Assim, o
resultado de empilhar o s´ımbolo a na pilha y ´e a pilha ay. O resultado de desempilhar o elemento do topo da pilha ay ´e a pilha y. A pilha vazia ser´a representada pela palavra λ.
No Cap´ıtulo 2, mostrou-se que a configura¸c˜ao instantˆanea de um AF ´e um par [e, y], em que e ´e o estado atual do autˆomato e y, o restante da palavra de entrada. A configura¸c˜ao instantˆanea consta das informa¸c˜oes necess´arias para o autˆomato prosseguir no reconhecimento da palavra de entrada em certo instante. Em um autˆomato de pilha, ela ser´a uma tripla [e, y, z], na qual e ´e o estado atual, y ´e o restante da palavra de entrada, e z ´e o conte´udo da pilha. Como explicado na Se¸c˜ao 2.1.1, usa-se a nota¸c˜ao c ⊢ c′ para dizer que a configura¸c˜ao instantˆanea c′ ´e o resultado de uma transi¸c˜ao a partir da configura¸c˜ao instantˆanea c. Com isso, por exemplo, pode-se expressar a seguinte computa¸c˜ao para o APD do Exemplo 70, mostrado na Figura 3.2, quando a palavra de entrada for (a*(a+a)):
[ap, (a ∗ (a + a)), λ] ⊢ [ap, a ∗ (a + a)), X] por 1 ⊢ [fp, ∗(a + a)), X] por 2 ⊢ [ap, (a + a)), X] por 5 ⊢ [ap, a + a)), XX] por 1 ⊢ [fp, +a)), XX] por 2 ⊢ [ap, a)), XX] por 4 ⊢ [fp, )), XX] por 1
⊢ [fp, ), X] por 3
⊢ [fp, λ, λ] por 3. N˜ao h´a transi¸c˜ao que se aplique a ⊢ [fp, λ, λ].
Outro exemplo:
λ, λ/X
Figura 3.3 Um APD com computa¸c˜oes ilimitadas.
N˜ao h´a transi¸c˜ao que se aplique a [fp, ), λ]. Esse segundo exemplo mostra que o APD pode n˜ao consumir toda a palavra de entrada. Usando a met´afora propiciada pelo esquema da Figura 3.1, em que a cada transi¸c˜ao corresponde uma “instru¸c˜ao” da m´aquina, diz-se que um AP pode parar sem consumir toda a palavra de entrada.
Para uma palavra ser reconhecida ´e necess´ario que trˆes condi¸c˜oes sejam satisfeitas simultaneamente : (1) um estado final seja atingido (2) a palavra seja totalmente con-sumida e (3) a pilha esteja vazia. Em outras palavras, uma palavra w ´e reconhecida se a computa¸c˜ao com in´ıcio na configura¸c˜ao inicial [i, w, λ] atingir a configura¸c˜ao [f, λ, λ] em que f ´e estado final. Assim, para o APD do Exemplo 70, a palavra (a*(a+a)) ´e reconhecida, como mostra a primeira computa¸c˜ao descrita. A palavra a) n˜ao ´e reco-nhecida, pois o AP n˜ao consome toda a palavra, como mostra a segunda computa¸c˜ao apresentada. E a palavra (a n˜ao ´e reconhecida, pois o APD para com a pilha n˜ao vazia:
[ap, (a, λ] ⊢ [ap, a, X] por 1 ⊢ [fp, λ, X] por 2.
N˜ao h´a transi¸c˜ao que se aplique a [fp, λ, X]. ´
E interessante notar que existem APs que n˜ao param para algumas entradas, ou mesmo para todas as entradas, como mostra o pr´oximo exemplo.
Exemplo 71 Um exemplo conciso de um AP com computa¸c˜oes de tamanho ilimitado seria aquele com alfabeto de entrada {1} e com o diagrama de estados exposto na Figura 3.3. Para toda palavra em {1}+, pode-se dizer que o APD n˜ao para, visto
que o primeiro s´ımbolo nunca ´e lido e a ´unica transi¸c˜ao existente ´e sempre aplic´avel. Em particular:
[0, 1, λ] ⊢ [0, 1, X] ⊢ [0, 1, XX] . . .
Para a palavra λ, a transi¸c˜ao tamb´em ´e aplic´avel e tˆem-se computa¸c˜oes de todo tama-nho. Pergunta: para a palavra de entrada λ, deve-se considerar que o APD para ou n˜ao? A palavra λ ´e reconhecida ou n˜ao?
Na pr´oxima se¸c˜ao, ser´a definido formalmente o conceito de autˆomato de pilha de-termin´ıstico e apresentados alguns exemplos. O problema levantado no Exemplo 71 pode ser resolvido formalizando-se convenientemente a no¸c˜ao de reconhecimento.
3.2
Autˆ
omatos de Pilha Determin´ısticos
Os autˆomatos de pilha determin´ısticos (APDs) s˜ao especialmente importantes, j´a que lidam com uma classe de linguagens para as quais h´a reconhecedores eficientes.
A defini¸c˜ao de autˆomato de pilha determin´ıstico, basicamente, acrescenta uma pilha a um AFD. Para que haja determinismo, n˜ao dever´a ser poss´ıvel mais de uma transi¸c˜ao ser definida para uma mesma configura¸c˜ao instantˆanea; em outras palavras, em um es-tado qualquer do APD, qualquer que seja o pr´oximo s´ımbolo de entrada e qualquer que seja a situa¸c˜ao atual da pilha, no m´aximo uma transi¸c˜ao dever´a ser poss´ıvel. A de-fini¸c˜ao a seguir captura exatamente as situa¸c˜oes em que duas transi¸c˜oes podem ocorrer simultaneamente para alguma configura¸c˜ao instantˆanea.
Defini¸c˜ao 33 Seja uma fun¸c˜ao de transi¸c˜aoδ : E ×Σλ×Γλ→ E ×Γ∗. Duas transi¸c˜oes
δ(e1, a1, b1) = [e′1, z1] e δ(e2, a2, b2) = [e′2, z2] s˜ao ditas compat´ıveis se e somente se:
e1= e2 e (a1= a2 ou a1= λ ou a2= λ) e (b1 = b2 ou b1 = λ ou b2 = λ).
Note-se, na Defini¸c˜ao 33, que a compatibilidade n˜ao depende dos estados destino nem das palavras a empilhar. Para algumas pessoas pode parecer mais intuitivo o complemento da express˜ao apresentada na defini¸c˜ao: duas transi¸c˜oes δ(e1, a1, b1) =
[e′1, z1] e δ(e2, a2, b2) = [e′2, z2] s˜ao n˜ao compat´ıveis se e somente se:
e16= e2 ou (a16= a2 e a1 6= λ e a2 6= λ) ou (b16= b2 e b1 6= λ e b26= λ).
Apesar de um APD admitir transi¸c˜oes sob λ, ele n˜ao admite transi¸c˜oes compat´ıveis. Logo, qualquer configura¸c˜ao instantˆanea que seja atingida ter´a no m´aximo uma suces-sora.
Defini¸c˜ao 34 Um autˆomato de pilha determin´ıstico(APD ) ´e uma sˆextupla (E, Σ, Γ, δ, i, F ),
em que
• E ´e um conjunto finito de um ou mais elementos denominados estados; • Σ ´e o alfabeto de entrada;
• Γ ´e o alfabeto de pilha;
• δ, a fun¸c˜ao de transi¸c˜ao, ´e uma fun¸c˜ao parcial de E × Σλ× Γλ para E × Γ∗, sem transi¸c˜oes compat´ıveis;
• i, um estado de E, ´e o estado inicial;
• F , subconjunto de E, ´e o conjunto de estados finais.
As seguintes raz˜oes fazem que n˜ao haja uma fun¸c˜ao ˆδ similar `aquela do Cap´ıtulo 2: • Pode haver computa¸c˜oes que n˜ao terminam, como ficou claro na Se¸c˜ao 3.1. • Al´em do(s) estado(s) atingido(s), ´e importante saber o conte´udo da pilha. Assim, em vez de uma fun¸c˜ao ˆδ, ser´a usada a rela¸c˜ao ⊢ definida a seguir.
1 2 a, λ/X
b, X/λ
b, X/λ
Figura 3.4 APD para {anbn| n ∈ N}.
Defini¸c˜ao 35 Seja um APD M = (E, Σ, Γ, δ, i, F ). A rela¸c˜ao⊢⊆ (E × Σ∗× Γ∗)2, para
M , ´e tal que para todo e, e′ ∈ E, a ∈ Σλ, b ∈ Γλ ex ∈ Γ∗:
[e, ay, bz] ⊢ [e′, y, xz] para todo y ∈ Σ∗ ez ∈ Γ∗ se, e somente se,δ(e, a, b) = [e′, x].
Utilizando a rela¸c˜ao⊢, que corresponde ao fecho reflexivo e transitivo de ⊢, define-se∗ a seguir o que ´e a linguagem reconhecida (aceita) por um APD.
Defini¸c˜ao 36 Seja um APD M = (E, Σ, Γ, δ, i, F ). A linguagem reconhecida por M ´e
L(M ) = {w ∈ Σ∗ | [i, w, λ]⊢ [e, λ, λ] para algum e ∈ F }.∗
Uma palavraw tal que [i, w, λ]⊢ [e, λ, λ], em que e ∈ F , ´e dita ser reconhecida (aceita)∗
porM .
Exemplo 72 No Exemplo 50, p´agina 87, mostrou-se que o conjunto {anbn| n ∈ N}
n˜ao ´e uma linguagem regular. Ela ´e reconhecida pelo autˆomato de pilha determin´ıstico ({1, 2}, {a, b}, {X}, δ, 1, {1, 2}), em que δ ´e dada por:
δ(1, a, λ) = [1, X]; δ(1, b, X) = [2, λ]; δ(2, b, X) = [2, λ].
O diagrama de estados est´a ilustrado na Figura 3.4.
No exemplo anterior, a pilha foi utilizada para conter o n´umero de as em excesso (com rela¸c˜ao ao n´umero de bs) lido at´e o momento atual; e os dois estados garantem que o processamento dos as anteceda o dos bs. Veja-se, ent˜ao, que parte das informa¸c˜oes coletadas (at´e certo instante do processamento) ´e armazenada na pilha e parte nos estados. Evidentemente, o n´umero de as s´o pode ser anotado na pilha, visto que ele pode ser um n´umero natural qualquer. Os dois exemplos a seguir, mostram que `as vezes pode-se escolher entre guardar uma informa¸c˜ao em estados ou na pilha. (Na Se¸c˜ao 3.4.4 ser´a visto que, para a vers˜ao n˜ao determin´ıstica, toda informa¸c˜ao pode ser guardada na pilha, o estado inicial servindo apenas para “dar partida”.)
ig m0 m1 0, λ/F 1, λ/F 0, λ/X 1, X/λ 1, F/λ 1, λ/X 0, X/λ 0, F/λ
Figura 3.5 APD para n´umero igual de 0s e 1s/vers˜ao 1.
Exemplo 73 A Figura 3.5 apresenta o diagrama de estados de um APD M que reco-nhece a linguagem {w ∈ {0, 1}∗| n
0(w) = n1(w)}. Tem-se que
M = ({ig, m0, m1}, {0, 1}, {Z, U, F}, δ, ig, {ig}) sendo δ dada por:
1. δ(ig, 0, λ) = [m0, F]; 2. δ(ig, 1, λ) = [m1, F]; 3. δ(m0, 0, λ) = [m0, X]; 4. δ(m0, 1, X) = [m0, λ]; 5. δ(m0, 1, F) = [ig, λ]; 6. δ(m1, 1, λ) = [m1, X]; 7. δ(m1, 0, X) = [m1, λ]; 8. δ(m1, 1, F) = [ig, λ].
No estado ig a pilha estar´a vazia e, al´em disso, o n´umero de 0s ser´a igual ao de 1s. O estado m0 ´e atingido se e somente se o n´umero de 0s lido at´e o momento ´e maior do que o de 1s; neste caso, a pilha cont´em o excesso de 0s com rela¸c˜ao ao n´umero de 1s. Analogamente, o estado m1 ´e atingido se e somente se o n´umero de 1s lido at´e o momento ´e maior do que o de 0s; no caso, a pilha cont´em o excesso de 1s com rela¸c˜ao a 0s. Portanto, a informa¸c˜ao de que o n´umero de 0s ´e igual ao de uns (estado ig) ou o de 0s ´e maior que o de 1s (estado m0) ou o de 1s ´e maior que o de 0s (estado m1) ´e dada pelos estados. J´a a informa¸c˜ao do excesso de um dos s´ımbolos com rela¸c˜ao ao outro ´e dado pela pilha.
A seguinte computa¸c˜ao mostra que 001110 pertence `a linguagem reconhecida por M : [ig, 001110, λ] ⊢ [m0, 01110, F] por 1 ⊢ [m0, 1110, XF] por 3 ⊢ [m0, 110, F] por 4 ⊢ [ig, 10, λ] por 5 ⊢ [m1, 0, F] por 2 ⊢ [ig, λ, λ] por 7.
= 6= 1, λ/UF 0, λ/ZF λ, F/λ 0, U/λ 0, Z/ZZ 1, U/UU 1, Z/λ
Figura 3.6 APD para n´umero igual de 0s e 1s/vers˜ao 2.
No exemplo a seguir, a informa¸c˜ao de qual s´ımbolo est´a em excesso, que no exemplo anterior ´e dada pelos estados, ´e colocada na pilha.
Exemplo 742 A Figura 3.6 apresenta o diagrama de estados de um outro APD que reconhece a linguagem {w ∈ {0, 1}∗| n
0(w) = n1(w)}. Observe que, como requerido,
n˜ao h´a transi¸c˜oes compat´ıveis. Ap´os lido um prefixo x da palavra de entrada:
• se n0(x) > n1(x), o estado atual ´e 6= e a pilha cont´em ZnF, sendo n = n0(x) −
n1(x);
• se n1(x) > n0(x), o estado atual ´e 6= e a pilha cont´em UnF, sendo n = n1(x) −
n0(x);
• se n0(x) = n1(x), o estado atual ´e = e a pilha est´a vazia ou o estado atual ´e 6= e
a pilha cont´em F.
No caso em que n0(x) = n1(x) e o estado atual ´e 6= e a pilha cont´em F, a ´unica transi¸c˜ao
aplic´avel ´e a de 6= para = sob λ substituindo F por λ, mesmo que exista um pr´oximo s´ımbolo a ser lido.
Os Exemplos 73 e 74 utilizam uma t´ecnica que possibilita marcar o fundo da pi-lha: foi introduzido um s´ımbolo de pilha (F) especificamente para isso. Algumas for-maliza¸c˜oes de APDs incluem um s´ımbolo especial para tal prop´osito. No entanto, a introdu¸c˜ao de um s´ımbolo especial de fundo de pilha n˜ao aumenta o poder de reco-nhecimento dos APDs, j´a que um s´ımbolo de pilha comum pode fazer seu papel, como mostram os exemplos citados. A seguir mais um exemplo de uso de marca¸c˜ao do fundo de pilha.
Exemplo 75 A Figura 3.7 mostra o diagrama de estados de um APD que reconhece {0m1n| m ≤ n}.
Novamente, de forma similar ao que se fez no exemplo da Figura 3.5, o marcador F´e usado para detectar quando o fundo de pilha ´e atingido, que ´e quando, ao ler o pr´oximo 1, o n´umero de 1s se torna igual ao de 0s.
2
O APD apresentado nesse exemplo foi desenvolvido por Jonatan Schr¨oeder, na ´epoca (segundo semestre de 2000), aluno da UFPR.
0, λ/F 1, λ/λ 0, F/XF 0, X/XX 1, X/λ 1, F/λ 1, X/λ 1, F/λ 1, λ/λ
Figura 3.7 Mais um APD com marca¸c˜ao de fundo de pilha.
0s 1s f 0, λ/X 1, X/λ #, λ/λ 1, X/λ #, λ/λ λ, X/λ
Figura 3.8 APD com s´ımbolo de final de palavra.
Existem linguagens que podem ser reconhecidas por autˆomatos de pilha n˜ao deter-min´ısticos, mas que n˜ao podem ser reconhecidas por APDs, como ser´a visto na pr´oxima se¸c˜ao. Dentre essas, existem algumas que passam a ser reconhecidas por APDs, caso haja um s´ımbolo espec´ıfico para finalizar a palavra de entrada. Segue um exemplo. Exemplo 76 A Figura 3.8 apresenta o diagrama de estados de um APD que reconhece a linguagem
{0m1n# | m ≥ n}.
Note que o s´ımbolo # s´o ´e utilizado para finalizar as palavras da linguagem. A lingua-gem similar, sem tal s´ımbolo,
{0m1n| m ≥ n},
n˜ao pode ser reconhecida por APD, como pode ser verificado.3
Observe que, para cada 0, alguma coisa deve ser empilhada para, no futuro, garantir-se que o n´umero de 1s n˜ao ultrapasse o de 0s. Mas, ap´os lido o prefixo de 0s, caso possa ser lido mais algum 1 (conforme indicado pela pilha), pode-se tamb´em terminar a palavra. Nesse ´ultimo caso, a pilha deve ser esvaziada sem leitura de mais s´ımbolos. O s´ımbolo para indicar final de palavra propicia, justamente, reconhecer deterministi-camente o momento de parar a leitura e esvaziar a pilha.
3
Na verdade, essa linguagem pode ser reconhecida por APD, mas com outro crit´erio de reconheci-mento, como ser´a visto na Se¸c˜ao 3.3.
A defini¸c˜ao de reconhecimento dada na Defini¸c˜ao 36, p´agina 139, n˜ao faz referˆencia `
a parada da m´aquina. Assim, por exemplo, a linguagem reconhecida pelo APD cujo dia-grama de estados est´a ilustrado na Figura 3.3, p´agina 137, ´e {λ}, n˜ao sendo importante se o APD para ou n˜ao para essa entrada.
Ao contr´ario dos autˆomatos finitos, os autˆomatos de pilha tˆem o seu poder aumen-tado quando se introduz n˜ao determinismo, como ser´a visto na pr´oxima se¸c˜ao. Depois, na Se¸c˜ao 3.4, ser˜ao estudadas as gram´aticas livres do contexto, que geram exatamente as linguagens reconhec´ıveis por autˆomatos de pilha. Isso ´e importante, j´a que, na maio-ria das situa¸c˜oes que ocorrem na pr´atica, ´e mais f´acil e conveniente obter uma gram´atica para a linguagem e, a partir da gram´atica, obter o autˆomato de pilha (determin´ıstico ou n˜ao).
Exerc´ıcios
1. Mostre que duas transi¸c˜oes s˜ao compat´ıveis (veja a Defini¸c˜ao 33, p´agina 138) se, e somente se, elas podem ocorrer simultaneamente para alguma configura¸c˜ao instantˆanea.
2. Construa APDs para as seguintes linguagens: a) {0n12n| n ≥ 0}; b) {03n12n| n ≥ 0}; c) {w0wR| w ∈ {1, 2}∗}; d) {anbkcn| n, k ≥ 0}; e) {anbicj| n = i + j}; f ) {0m1n| m < n}; g) {0n1n012| n ∈ N}; h) {0m1n# | m 6= n}; i) {w# | w ∈ {0, 1}∗ e n 0(w) > n1(w)}.
3. Explique por que n˜ao h´a APD para as seguintes linguagens: a) {wwR| w ∈ {1, 2}∗};
b) {0m1n| m > n};
c) {0m1n| m 6= n};
d) {w ∈ {0, 1}∗| n
0(w) > n1(w)}.
4. Construa um APD que reconhe¸ca toda palavra com parˆenteses balanceados. Exemplos de palavras da linguagem: λ, (), (())(). Exemplos de palavras que n˜ao pertencem `a linguagem: (, )(, ()).
Generalize para o caso em que existem n tipos de parˆenteses. Nesse caso, considere que cada ocorrˆencia de abre parˆenteses, ai, deve ser seguida `a direita por uma
uma palavra com parˆenteses balanceados. Se i = 2, a1 = (, b1 = ), a2 = [,
b2 = ], seriam exemplos de palavras da linguagem: λ, (), [()](), [[()]()]([]).
Exemplos de palavras que n˜ao pertencem `a linguagem: (, ][, ()], (], ([)]. 5. Construa um APD que reconhe¸ca as express˜oes aritm´eticas na forma prefixada,
EAPre, definidas recursivamente como segue: a) a ´e uma EAPre;
b) se x e y s˜ao EAPre, ent˜ao +xy e −xy s˜ao EAPre.
Dica: Sempre que ler + ou −, empilhe dois Xs, para “lembrar” de ler duas subexpress˜oes `a frente.
6. Construa um APD que reconhe¸ca as express˜oes aritm´eticas na forma posfixada, EAPos, definidas recursivamente como segue:
(a) a ´e uma EAPos;
(b) se x e y s˜ao EAPos, ent˜ao xy+ e xy− s˜ao EAPos.
Dica: Use os seguintes fatos, f´aceis de mostrar por indu¸c˜ao: o n´umero de as ´e um a mais que o de operadores, e qualquer palavra que tenha mais as que operadores ´e prefixo de EAPos.
3.3
Autˆ
omatos de Pilha N˜
ao Determin´ısticos
A diferen¸ca entre um autˆomato de pilha determin´ıstico e um n˜ao determin´ıstico ´e que esse ´ultimo pode conter transi¸c˜oes compat´ıveis, como pode ser visto na defini¸c˜ao a seguir.
Defini¸c˜ao 37 Um autˆomato de pilha n˜ao determin´ıstico (APN ) ´e uma sˆextupla (E, Σ, Γ, δ, I, F ), em que
• E, Σ, Γ e F s˜ao como em APDs;
• δ, a fun¸c˜ao de transi¸c˜ao, ´e uma fun¸c˜ao parcial de E × Σλ× Γλ para D, sendo D constitu´ıdo dos subconjuntos finitos de E × Γ∗;
• I, um subconjunto de E, ´e o conjunto de estados iniciais.
A rela¸c˜ao ⊢ da Defini¸c˜ao 35, p´agina 139, ser´a utilizada para definir o reconheci-∗ mento para APNs, de forma similar ao reconhecimento para APDs apresentado na Defini¸c˜ao 36.
Defini¸c˜ao 38 Seja um APN M = (E, Σ, Γ, δ, I, F ). A linguagem reconhecida por M ´e
= 6= 1, λ/U 0, λ/Z λ, λ/λ 0, U/λ 0, Z/ZZ 1, U/UU 1, Z/λ Figura 3.9 APN para n´umero igual de 0s e 1s.
Uma palavra w tal que [i, w, λ] ⊢ [e, λ, λ], sendo i ∈ I e e ∈ F , ´e dita ser reconhecida∗ (aceita) por M .
Segue um exemplo que mostra a evolu¸c˜ao de um APD para um APN equivalente “mais conciso”.
Exemplo 77 No Exemplo 74, p´agina 141, foi visto um APD para {w ∈ {0, 1}∗| n0(w) =
n1(w). Nele ´e usado o s´ımbolo F para marcar o fundo da pilha, de forma que, quando
os n´umeros de 0s e de 1s se tornam idˆenticos (mesmo que a palavra n˜ao tenha sido toda processada ainda), seja ativada a transi¸c˜ao para o estado final =. Ora, um autˆomato
n˜ao determin´ıstico pode “adivinhar” quando a pilha se torna vazia e fazer a transi¸c˜ao citada. Assim, um APN equivalente ao APD do Exemplo 74 seria:
N = ({=, 6=}, {0, 1}, {Z, U}, δ, {=}, {=}), em que δ ´e dada por:
1. δ(=, 0, λ) = {[6=, Z]}; 2. δ(=, 1, λ) = {[6=, U]}; 3. δ(6=, 0, Z) = {[6=, ZZ]}; 4. δ(6=, 0, U) = {[6=, λ]}; 5. δ(6=, 1, U) = {[6=, UU]}; 6. δ(6=, 1, Z) = {[6=, λ]}; 7. δ(6=, λ, λ) = {[=, λ]}.
O diagrama de estados de N pode ser visto na Figura 3.9. Note que, a ´unica diferen¸ca, com rela¸c˜ao ao APD do Exemplo 74, ´e que, na figura, o s´ımbolo F foi substitu´ıdo por λ. Observe que a transi¸c˜ao 7 ´e compat´ıvel com as transi¸c˜oes 3 a 6, mas de uma forma restrita: partindo-se do estado 6=, quando a pilha est´a vazia, apenas a transi¸c˜ao 7 ´e aplic´avel; somente quando a pilha n˜ao est´a vazia, uma das transi¸c˜oes 3 a 6 ´e aplic´avel, al´em da transi¸c˜ao 7. Assim, se for dada prioridade sempre para as transi¸c˜oes 3 a 6, o comportamento do APN ´e an´alogo ao do APD do Exemplo 74. Isso evidencia que esse APN reconhece toda palavra que o referido APD reconhece. Contudo, tal APN
= 6= 1, λ/U 0, λ/Z λ, λ/λ 0, U/λ 1, Z/λ (a) O segundo 0, λ/Z 1, λ/U 0, U/λ 1, Z/λ (b) O terceiro
Figura 3.10 Mais dois APNs para n´umero igual de 0s e 1s.
1 2 λ, λ/λ 0, λ/λ 1, λ/λ 0, λ/0 1, λ/1 0, 0/λ 1, 1/λ
Figura 3.11 APN para pal´ındromos sobre {0, 1}∗.
continua n˜ao podendo reconhecer palavras com n´umeros diferentes de 0s e 1s, como pode ser notado verificando-se o padr˜ao de empilhamentos e desempilhamentos.
Na realidade, o APN N ´e menos conciso do que poderia ser. As transi¸c˜oes 3 e 5 s˜ao desnecess´arias. O mesmo efeito da transi¸c˜ao 3 pode ser conseguido aplicando-se, em sequˆencia, as transi¸c˜oes 7 (compat´ıvel com a 3) e 1, e o mesmo efeito da transi¸c˜ao 5 pode ser obtido aplicando-se, em sequˆencia, as transi¸c˜oes 7 (compat´ıvel com a 5) e 2. Obt´em-se, com isso, o APN cujo diagrama de estados est´a mostrado na Figura 3.10a. Analisando-se esse ´ultimo diagrama de estados, levando-se em conta que o reconheci-mento se d´a quando a pilha fica vazia, chega-se ao APN equivalente cujo diagrama de estados est´a ilustrado na Figura 3.10b.
A seguir, ´e apresentado um APN para uma linguagem que n˜ao pode ser reconhecida por APDs.
Exemplo 78 Na Figura 3.11 est´a representado o diagrama de estados para um APN que reconhece a linguagem {w ∈ {0, 1}∗| w = wR}.
Caso uma palavra w seja pal´ındromo, existir´a uma computa¸c˜ao para w em que w ´e consumida e a pilha fica vazia; para tal computa¸c˜ao, uma das trˆes transi¸c˜oes de 1 para 2 ´e percorrida:
• se |w| for par, ser´a percorrida a transi¸c˜ao de 1 para 2 sob λ;
• se |w| for ´ımpar e o s´ımbolo do meio for 0, ser´a percorrida a transi¸c˜ao de 1 para 2 sob 0;
• se |w| for ´ımpar e o s´ımbolo do meio for 1, ser´a percorrida a transi¸c˜ao de 1 para 2 sob 1.
Ao processar uma palavra da esquerda para a direita, quando atinge o meio da palavra, n˜ao h´a como o autˆomato reconhecer tal fato, para, a partir da´ı, comparar a segunda metade com a primeira. Assim sendo, n˜ao h´a como construir um APD para a linguagem dos pal´ındromos.
Pela Defini¸c˜ao 38, a linguagem reconhecida por um APN M = (E, Σ, Γ, δ, I, F ) ´e
L(M ) = {w ∈ Σ∗| [i, w, λ]⊢ [e, λ, λ] para algum i ∈ I e e ∈ F }.∗
Uma defini¸c˜ao alternativa, que levaria a uma concep¸c˜ao diferente de APNs, ´e aquela em que o reconhecimento de uma palavra se d´a ao ser atingido um estado final, ap´os ser consumida a palavra de entrada, esteja a pilha vazia ou n˜ao. Usando o ´ındice F em LF(M ) para significar reconhecimento por estado final, segue tal defini¸c˜ao alternativa,
mais formalmente.
Defini¸c˜ao 39 Seja um APN M = (E, Σ, Γ, δ, I, F ). A linguagem reconhecida por M por estado final ´e
LF(M ) = {w ∈ Σ∗| [i, w, λ] ∗
⊢ [e, λ, y] para algum i ∈ I, e ∈ F e y ∈ Γ∗}.
Uma palavra w tal que [i, w, λ] ⊢ [e, λ, y], sendo i ∈ I, e ∈ F e y ∈ Γ∗ ∗, ´e dita ser
reconhecida (aceita) por M por estado final.
O reconhecimento, segundo a Defini¸c˜ao 38, ser´a denominado, a seguir,
reconheci-mento por pilha vazia e estado final.
Pode-se mostrar que uma linguagem pode ser reconhecida por pilha vazia e es-tado final se, e somente se, pode ser reconhecida por eses-tado final, como ser´a visto no Teorema 18 no final desta se¸c˜ao.
O exemplo a seguir apresenta dois autˆomatos de pilha que reconhecem a mesma linguagem, um deles utilizando reconhecimento por pilha vazia e estado final, e o outro usando reconhecimento por estado final.
Exemplo 79 Seja o problema de determinar um APN que reconhe¸ca a linguagem L = {0m1n| m ≥ n}.
A Figura 3.12a mostra o diagrama de estados de um APN M tal que L(M ) = L, sendo que M reconhece por pilha vazia e estado final, enquanto a Figura 3.12b ilustra o diagrama de estados de um APN M′ tal que LF(M′) = L, sendo que M′ reconhece
por estado final. Veja que, por coincidˆencia, o diagrama de estados da Figura 3.12b ´e idˆentico ao da Figura 3.4, p´agina 139, que reconhece a linguagem {anbn| n ≥ 0}
por pilha vazia e estado final (substituindo-se 0 por a e 1 por b); assim, L(M′) = {0n1n| n ≥ 0}. Observe tamb´em que L
F(M ) = L: coincidentemente, o APN cujo
diagrama de estados pode ser observado na Figura 3.12a reconhece a mesma linguagem para os dois m´etodos de reconhecimento.
0 1 1 , X/λ 0, λ/λ
0, λ/X 1, X/λ
(a) Aceita¸c˜ao por pilha vazia e estado final
0 1 1
, X/λ
0, λ/X 1, X/λ
(b) Aceita¸c˜ao por estado final
Figura 3.12 APNs para {0m1n| m ≥ n}.
Outra defini¸c˜ao alternativa ´e aquela em que o reconhecimento de uma palavra se d´a quando a pilha fica vazia, ap´os ser consumida a palavra de entrada. Nesse caso, n˜ao h´a o conceito de estado final. Usando o ´ındice V em LV(M ) para significar reconhecimento por pilha vazia, segue tal defini¸c˜ao alternativa, observando a ausˆencia do conjunto de estados finais.
Defini¸c˜ao 40 Seja um APN M = (E, Σ, Γ, δ, I). A linguagem reconhecida por M por pilha vazia ´e
LV(M ) = {w ∈ Σ∗| [i, w, λ] ∗
⊢ [e, λ, λ] para algum i ∈ I e e ∈ E}.
Uma palavra w tal que [i, w, λ] ⊢ [e, λ, λ], sendo que i ∈ I, ´e dita ser reconhecida∗ (aceita) por M por pilha vazia.
Note que, por essa defini¸c˜ao, λ ´e sempre reconhecida, j´a que a pilha come¸ca vazia. Ser´a mostrado tamb´em, no Teorema 18, que uma linguagem com a palavra λ pode ser reconhecida por pilha vazia e estado final se, e somente se, pode ser reconhecida por pilha vazia.
O APN cujo diagrama de estados est´a ilustrado na Figura 3.12a reconhece a lin-guagem {0m1n| m ≥ n} tamb´em por pilha vazia, visto que todos os seus estados s˜ao
estados finais. Ali´as, se um APN M = (E, Σ, Γ, δ, I) reconhece LV(M ), ent˜ao o APN
M′ = (E, Σ, Γ, δ, I, E) (observe que todos os estados s˜ao finais em M′) reconhece
LV(M ) por pilha vazia e estado final.
Exemplo 80 Seja o APN cujo diagrama de estados est´a representado na Figura 3.13. Tal APN reconhece a linguagem {0m1n| m ≤ n} por pilha vazia. Considerando todos
os seus estados como estados finais, ele reconhece a mesma linguagem por pilha vazia e estado final.
O teorema a seguir mostra a equivalˆencia dos trˆes m´etodos de reconhecimento. A equivalˆencia segue do uso de trˆes m´etodos: (a) um que mostra como obter um AP que reconhece por estado final equivalente a um que reconhe¸ca por pilha vazia e estado final, (b) outro que revela como chegar a um AP que reconhece por pilha vazia equivalente a um que reconhe¸ca por estado final, e (c) finalmente, um m´etodo que mostra como
0 1 1 , X/λ 0, λ/X
λ, λ/X 1, X/λ
Figura 3.13 APN para {0m1n| m ≤ n}.
M · · · i′ i1 .. . im f1 fn .. . g λ, λ/F λ, λ/F λ, F/λ λ, F/λ I F
Figura 3.14 Obten¸c˜ao de AP pelo M´etodo 12.
obter um AP que reconhece por estado final e pilha vazia equivalente a um outro que reconhe¸ca por pilha vazia. Antes do teorema, seguem os trˆes m´etodos.
M´etodo 12 De reconhecimento padr˜ao ao por estado final
Seja um APN M = (E, Σ, Γ, δ, I, F ). ´E poss´ıvel obter, a partir de M , um APN M′ de
modo que LF(M′) = L(M ). A id´eia central ´e utilizar um s´ımbolo de pilha novo para
marcar o fundo da pilha, de forma que M′ possa reconhecer quando M estaria com a pilha vazia.
Ser˜ao usados, al´em dos estados em E, mais dois estados i′, g 6∈ E, e, al´em dos s´ımbolos de Γ, mais um s´ımbolo de pilha F 6∈ Γ. Basta fazer M′ = (E ∪ {i′, g}, Σ, Γ ∪ {F}, δ′, {i′}, {g}) (veja a Figura 3.14 para uma representa¸c˜ao esquem´atica de M′), tal que δ′ inclui δ mais as seguintes transi¸c˜oes:
• para cada ik ∈ I, δ′(i′, λ, λ) = {[ik, F]};
• para cada fj ∈ F , δ′(fj, λ, F) = {[g, λ]}.
M´etodo 13 De reconhecimento por estado final ao por pilha vazia
Seja um APN M = (E, Σ, Γ, δ, I, F ). Um APN M′ tal que LV(M′) = LF(M ) ∪ {λ}
seria M′ = (E ∪{i′, g, h}, Σ, Γ∪{F}, δ′, {i′}) (veja a Figura 3.15 para uma representa¸c˜ao
esquem´atica de M′), tal que i′, g, h 6∈ E, F 6∈ Γ e δ′ inclui δ mais as seguintes transi¸c˜oes:
• para cada ik ∈ I, δ′(i′, λ, λ) = {[ik, F]};
M · · · i′ i1 .. . im f1 fn .. . g h λ, λ/F λ, λ/F λ, λ/λ λ, λ/λ λ, X/λ ∀X ∈ Γ λ, F/λ I F
Figura 3.15 Obten¸c˜ao de APN pelo M´etodo 13.
• para cada X ∈ Γ, δ(g, λ, X) = {[g, λ]}; • δ(g, λ, F) = {[h, λ]}.
O s´ımbolo de pilha F ´e utilizado aqui para evitar que a pilha fique vazia, exceto quando a palavra deva ser reconhecida. A pilha fica vazia se, e somente se, for atingido o estado h.
Teorema 18 Seja L uma linguagem. As seguintes afirmativas s˜ao equivalentes:
a) L pode ser reconhecida por pilha vazia e estado final. b) L pode ser reconhecida por estado final.
c) L ∪ {λ} pode ser reconhecida por pilha vazia. Prova
(a) → (b)
Seja um APN qualquer M . O AP M′, obtido de acordo com o M´etodo 12, ´e tal
que LF(M′) = L(M ), de onde se segue que se L pode ser reconhecida por pilha vazia
e estado final, ent˜ao L pode ser reconhecida por estado final. (b) → (c)
De um APN M que reconhe¸ca por estado final, pode-se construir via o M´etodo 13 um APN M′ tal que L
V(M′) = LF(M ) ∪ {λ}. Logo, se L pode ser reconhecida por
estado final, ent˜ao L ∪ {λ} pode ser reconhecida por pilha vazia. (c) → (a)
Como j´a foi ressaltado, um APN que reconhece por pilha vazia ´e um APN que reconhece por pilha vazia e estado final, bastando considerar todos os seus estados como estados finais. Ou seja, se M = (E, Σ, Γ, δ, I), um APN M′ tal L(M′) = LV(M )
seria, ent˜ao, M′ = (E, Σ, Γ, δ, I, E). Observe que, como LV(M ) cont´em λ, L(M′)
tamb´em cont´em. Embora n˜ao seja mostrado aqui como, ´e poss´ıvel tamb´em obter M′
Daqui para a frente, ser´a usada tamb´em a express˜ao AP para designar autˆomato de pilha (n˜ao determin´ıstico).
Exerc´ıcios
1. Seja o AP M = ({i, f }, {a, b}, {B, C}, δ, {i}, {f }), em que δ ´e dada por: δ(i, a, λ) = [i, B]
δ(i, λ, λ) = [f, λ] δ(f, b, B) = [f, C] δ(f, c, C) = [f, λ]
a) Exiba as computa¸c˜oes para as palavras aa, bb, aabcc e aabcbc. Quais destas palavras s˜ao reconhecidas por M ?
b) Que linguagem ´e reconhecida por M ?
2. Construa um AP com um alfabeto de pilha contendo apenas dois s´ımbolos, que reconhe¸ca {w ∈ {a, b, c, d}∗| w = wR}.
3. Para as seguintes linguagens, construa APD, se poss´ıvel. Se n˜ao for poss´ıvel, construa APN. a) {(01)n1(10)n| n ∈ N}; b) {(01)n0(10)n| n ∈ N}; c) {anb2nc2k| n, k ∈ N}; d) {anb2na2k| n, k ∈ N}; e) {anb2na2k| n ≥ 1, k ∈ N}; f ) {an(abc)n| n ∈ N}.
4. Construa APNs que reconhe¸cam as linguagens seguintes por pilha vazia e estado final:
a) {0n1n| n ≥ 0} ∪ {0n12n| n ≥ 0};
b) {0n1k| n ≤ k ≤ 2n};
c) {0n1n0k| n, k ≥ 0};
d) {0m1n| m > n}.
5. Construa APDs que reconhe¸cam {anbn| n ≥ 0}:
a) por estado final; b) por pilha vazia.
6. Construa APDs que reconhe¸cam por estado final as linguagens: a) {ambn| m 6= n};
b) O complemento de {ambn| m ≥ n}; c) O complemento de {anbn| n ≥ 0}.
7. Construa APNs que reconhe¸cam as linguagens do Exerc´ıcio 4:
a) por estado final; b) por pilha vazia.
8. Mostre que um APN em que ´e empilhado no m´aximo um s´ımbolo por transi¸c˜ao tem o mesmo poder que um APN normal.
9. Mostre como obter um APN, cuja pilha receba no m´aximo um s´ımbolo, que seja equivalente a um AFNλ dado.
10. Obtenha um APD que reconhe¸ca por estado final a linguagem L = {w ∈ {0, 1}∗| n0(w) 6=
n1(w)}. A partir dele, obtenha um APD que reconhe¸ca L{#} por pilha vazia e estado final.
11. Mostre que toda linguagem regular pode ser reconhecida por algum APD sob qualquer um dos trˆes crit´erios de reconhecimento. Para isso, mostre como obter, a partir de qualquer AFD, os APDs equivalentes para cada um dos crit´erios de reconhecimento.
12. Mostre como obter um AP M′a partir de um AP M , tal que L(M′) = L(M )−{λ}.
3.4
Gram´
aticas Livres do Contexto
O seguinte trecho ´e uma parte de uma gram´atica livre do contexto, na nota¸c˜ao BNF,4 que define uma parte da sintaxe de uma linguagem de programa¸c˜ao similar `aquela que ´e utilizada para a apresenta¸c˜ao dos algoritmos deste texto:
4
hprogramai ::= hdeclara¸c˜oesi ; hlista-de-cmdsi . ..
.
hlista-de-cmdsi ::= hcomandoi ; hlista-de-cmdsi | λ
hcomandoi ::= hcmd-enquantoi | hcmd-sei |
hcmd-atribui¸c˜aoi | · · ·
hcmd-enquantoi ::= enquantohexp-l´ogicai fa¸ca hlista-de-cmdsi fimenquanto hcmd-sei ::= sehexp-l´ogicai ent˜ao
hlista-de-cmdsi hsenaosesi hsenaoi fimse hsenaosesi ::= sen˜aosehexp-l´ogicai ent˜ao
hlista-de-cmdsi hsenaosesi | λ
hsenaoi ::= sen˜aohlista-de-cmdsi | λ
hcmd-atribui¸c˜aoi ::= hvari´aveli ← hexpress˜aoi
Nessa nota¸c˜ao, o lado esquerdo de uma regra ´e separado do lado direito pela sequˆencia ”::=“. As vari´aveis figuram entre “h” e “i”. Os outros s´ımbolos s˜ao termi-nais; por ordem de ocorrˆencia: “;”, enquanto, fa¸ca, fimenquanto, se, ent˜ao,fimse, sen˜aose, “←”.
Cada regra de uma gram´atica livre do contexto tem no lado esquerdo apenas uma vari´avel. No lado direito pode ser colocada uma palavra qualquer constitu´ıda por vari´aveis e/ou terminais.
Existem programas que aceitam uma gram´atica livre do contexto no formato BNF e produzem um analisador sint´atico para a mesma. Apesar da nota¸c˜ao BNF ser co-mumente mais adequada para a descri¸c˜ao de linguagens que ocorrem na pr´atica, como as linguagens de programa¸c˜ao, a nota¸c˜ao formal a ser introduzida na pr´oxima se¸c˜ao ´e mais adequada para o estudo de gram´aticas livres do contexto em geral. Ap´os isso, na Se¸c˜ao 3.4.2, ser˜ao apresentados os conceitos de ´arvore de deriva¸c˜ao e de ambiguidade de gram´aticas, muito importantes por terem grande repercuss˜ao em aplica¸c˜oes que en-volvem o uso de gram´aticas como base no processamento de linguagens. Depois, na Se¸c˜ao 3.4.3 ser´a abordado o problema de manipular as regras de uma gram´atica com o objetivo de que a gram´atica resultante tenha certas caracter´ısticas. Para finalizar, na Se¸c˜ao 3.4.4 ser´a mostrada a equivalˆencia dos formalismos de gram´aticas livres do contexto e autˆomatos de pilha.
3.4.1 Defini¸c˜ao e exemplos
Segue a defini¸c˜ao de gram´atica livre do contexto.
Defini¸c˜ao 41 Uma gram´atica livre do contexto (GLC ) ´e uma gram´atica (V, Σ, R, P ),
Para uma GLC, em cada passo de uma deriva¸c˜ao deve-se escolher, na forma sen-tencial, a vari´avel A a ser substitu´ıda pelo lado direito de uma regra com A do lado esquerdo. Ao se fazer tal substitui¸c˜ao, diz-se que A ´e expandida.
Observe que uma gram´atica regular ´e uma gram´atica livre do contexto especial, em que toda deriva¸c˜ao produz uma forma sentencial contendo uma ´unica vari´avel, que ´e sempre o s´ımbolo mais `a direita. Todavia, existem linguagens que n˜ao s˜ao regulares e que, portanto, n˜ao podem ser geradas por GRs, mas que podem ser geradas por GLCs. A seguir s˜ao mostrados alguns exemplos.
Exemplo 81 A linguagem n˜ao regular {0n1n| n ∈ N} ´e gerada pela gram´atica livre
do contexto G = ({P }, {0, 1}, R, P ), em que R consta das duas regras: P → 0P 1 | λ
As ´unicas palavras geradas por tal gram´atica s˜ao aquelas que podem ser geradas por n aplica¸c˜oes da regra P → 0P 1, n ≥ 0, seguidas de uma aplica¸c˜ao da regra P → λ. Esquematicamente: P ⇒ 0n nP 1n⇒ 0n1n. Logo, L(G) = {0n1n| n ∈ N}.
Exemplo 82 A gram´atica G, a seguir, gera os pal´ındromos sobre {0, 1}, ou seja, L(G) = {w ∈ {0, 1}∗| w = wR}. G = ({P }, {0, 1}, R, P ), em que R consta das cinco
regras:
P → 0P 0 | 1P 1 | 0 | 1 | λ
Aplicando-se as duas primeiras regras, gera-se qualquer forma sentencial do tipo wP wR,
para w ∈ {0, 1}∗. Por fim, para gerar uma palavra, aplica-se uma das trˆes ´ultimas regras
de G; a ´ultima, quando a palavra apresenta tamanho par, e uma das outras, quando ela tem tamanho ´ımpar.
Exemplo 83 A linguagem L = {w ∈ {0, 1}∗| n0(w) = n1(w)} ´e gerada pela gram´atica
G = ({P }, {0, 1}, R, P ), em que R consta das trˆes regras: P → 0P 1P | 1P 0P | λ
Como o lado direito de cada uma das trˆes regras possui n´umero igual de 0s e 1s, G s´o gera palavras de L. O fato de que G produz todas as palavras de L vem do fato de que para toda palavra w de L, tem-se um dos trˆes casos:
a) w = λ; nesse caso, basta aplicar a regra P → λ;
b) w = 0y para algum y ∈ {0, 1}∗ e y tem um 1 a mais que 0s; logo, y ´e da forma x1z, onde x tem n´umero igual de 0s e 1s e z tamb´em tem n´umero igual de 0s e 1s; assim, basta iniciar a deriva¸c˜ao de w com a primeira regra;
c) w = 1y para algum y ∈ {0, 1}∗ e y tem um 0 a mais que 1s; por motivo an´alogo
Nos casos (b) e (c), tˆem-se novamente (recursivamente) os trˆes casos aplicados para as subpalavras x e z. Com isso, obt´em-se um m´etodo para construir uma deriva¸c˜ao de qualquer palavra de L. A seguinte deriva¸c˜ao de 01010110 ilustra a aplica¸c˜ao do m´etodo subjacente, em que a vari´avel expandida ´e sempre a mais `a esquerda:
P ⇒ 0P 1P P → 0P 1P (x = 10; z = 0110) ⇒ 01P 0P 1P P → 1P 0P (x = λ; z = λ) ⇒ 010P 1P P → λ ⇒ 0101P P → λ ⇒ 01010P 1P P → 0P 1P (x = λ; z = 10) ⇒ 010101P P → λ ⇒ 0101011P 0P P → 1P 0P (x = λ; z = λ) ⇒ 01010110P P → λ ⇒ 01010110 P → λ.
O exemplo a seguir ilustra uma gram´atica que cont´em a essˆencia da especifica¸c˜ao da sintaxe das express˜oes aritm´eticas das linguagens de programa¸c˜ao usuais.
Exemplo 84 Seja a GLC ({E, T, F }, {a, +, ∗, (, )}, R, E), para express˜oes aritm´eticas, em que R consta das regras:
E → E+T | T T → T ∗F | F F → (E) | a
As duas primeiras regras dizem que uma express˜ao aritm´etica, E, ´e constitu´ıda por um ou mais termos, T s, somados. As duas seguintes dizem que um termo ´e composto de um ou mais fatores, F s, multiplicados. E as duas ´ultimas dizem que um fator ´e terminal aou, recursivamente, uma express˜ao aritm´etica entre parˆenteses. Essa gram´atica ser´a utilizada em v´arios exemplos daqui para a frente.
Adiante, na Se¸c˜ao 3.4.4, ser´a mostrado que as linguagens geradas por gram´aticas livres do contexto s˜ao exatamente as reconhecidas por autˆomatos de pilha. A defini¸c˜ao a seguir d´a um nome `a classe formada por tais linguagens.
Defini¸c˜ao 42 Uma linguagem ´e dita ser uma linguagem livre do contexto se existe
uma gram´atica livre do contexto que a gera.
Em geral, existem v´arias deriva¸c˜oes de uma mesma palavra da linguagem gerada por uma gram´atica. Note que no Exemplo 83, p´agina 154, inicia-se uma deriva¸c˜ao de 01010110por
E, ap´os isso, a vari´avel expandida ´e sempre a mais `a esquerda. Pode-se ver que a mesma palavra pode ser derivada expandindo-se sempre a vari´avel mais `a direita em vez da vari´avel mais `a esquerda. E mais, a mesma palavra pode ser derivada expandindo-se vari´aveis em ordem aleat´oria. Isto mostra que existem v´arias deriva¸c˜oes distintas para a palavra 01010110. O que tais deriva¸c˜oes tˆem em comum, al´em de gerar a mesma palavra? Esse assunto ser´a abordado na pr´oxima se¸c˜ao.
3.4.2 Deriva¸c˜oes e ambiguidade
Um conceito bastante ´util, base para muitas implementa¸c˜oes de compiladores de lin-guagens de programa¸c˜ao, ´e o de ´arvore de deriva¸c˜ao(AD). Uma AD captura a essˆencia de uma deriva¸c˜ao, a hist´oria da obten¸c˜ao de uma forma sentencial que n˜ao depende da ordem de aplica¸c˜ao das regras da GLC. A cada deriva¸c˜ao vai corresponder uma ´unica AD, mas a uma AD vai corresponder, quase sempre, uma quantidade muito grande de deriva¸c˜oes. Assim, pode-se dizer que as ADs particionam o conjunto de todas as deriva¸c˜oes de uma GLC em “deriva¸c˜oes equivalentes”: duas deriva¸c˜oes seriam equiva-lentes se, e somente se, correspondessem `a mesma AD.
Defini¸c˜ao 43 Seja uma GLC G = (V, Σ, R, P ). Uma ´arvore de deriva¸c˜ao (AD ) de uma
forma sentencial de G ´e uma ´arvore ordenada constru´ıda recursivamente como segue:
a) uma ´arvore sem arestas cujo ´unico v´ertice tem r´otulo P ´e uma AD; b) se X ∈ V ´e r´otulo de uma folha f de uma AD A, ent˜ao:
i. se X → λ ∈ R, ent˜ao a ´arvore obtida acrescentando-se a A mais um v´ertice v com r´otulo λ e uma aresta {f, v} ´e uma AD;
ii. se X → x1x2. . . xn∈ R, onde x1, x2, . . . , xn ∈ V ∪ Σ, ent˜ao a ´arvore obtida acrescentando-se aA mais n v´ertices v1,v2, . . . ,vn com r´otulosx1,x2, . . . ,
xn, nessa ordem, e n arestas {f, v1}, {f, v2}, . . . , {f, vn}, ´e uma AD. Se a sequˆencia dos r´otulos da fronteira da AD ´e a forma sentencialw, diz-se que a AD
´
e uma ´arvore de deriva¸c˜ao de w.
Exemplo 85 Seja a gram´atica do Exemplo 84 cujas regras s˜ao reproduzidas a seguir: E → E+T | T
T → T ∗F | F F → (E) | a
Na Figura 3.16, mostra-se uma AD de a*(a+a). Para a constru¸c˜ao de tal ´arvore, tomou-se como ponto de partida a deriva¸c˜ao:
E ⇒ T (regra E → T ) produzindo-se uma AD de T :
E
T
Em seguida, a deriva¸c˜ao evoluiu para: E ⇒ T (regra E → T )
⇒ T ∗F (regra T → T ∗F )
e a ´arvore correspondente (que ´e uma AD de T ∗F ) para: E
T
T ∗ F
Neste instante, tem-se duas op¸c˜oes para continuar a deriva¸c˜ao: E ⇒ T (regra E → T ) ⇒ T ∗F (regra T → T ∗F ) ⇒ F ∗F (regra T → F ) ou ent˜ao E ⇒ T (regra E → T ) ⇒ T ∗F (regra T → T ∗F ) ⇒ T ∗(E) (regra F → (E)). `
A esquerda, mostra-se a AD correspondente `a primeira deriva¸c˜ao, e `a direita, a AD correspondente `a segunda deriva¸c˜ao:
E T T ∗ F F E T T ∗ F ( E )
Prosseguindo-se por qualquer uma dessas alternativas, chega-se, ap´os uma deriva¸c˜ao de 11 passos, `a AD mostrada na Figura 3.16.
E T T ∗ F F ( E ) a E + T T F F a a
Figura 3.16 Uma ´arvore de deriva¸c˜ao de a*(a+a).
Observe que o n´umero de passos de qualquer deriva¸c˜ao que leva a uma AD X ´e o n´umero de v´ertices internos de X, j´a que a cada v´ertice interno corresponde a aplica¸c˜ao de uma regra (e vice-versa).
A estrutura da ´arvore de deriva¸c˜ao, muitas vezes, ´e utilizada para associar signifi-cado para as senten¸cas de uma linguagem, de forma similar ao que se faz em an´alise sint´atica de senten¸cas na l´ıngua portuguesa (em que se identifica sujeito, verbo, predi-cado etc.). Em portuguˆes, se a mesma senten¸ca pode ser desmembrada de mais de uma forma durante a an´alise, ent˜ao ela possui v´arios significados, e diz-se que ela ´e amb´ıgua. De forma an´aloga, se existir mais de uma AD de uma mesma palavra, provavelmente ela ter´a mais de um significado. Isso inspira a defini¸c˜ao a seguir.
Defini¸c˜ao 44 Uma GLC ´e denominada amb´ıgua quando existe mais de uma AD para
alguma senten¸ca que ela gera.
Observe, no entanto, que a gram´atica ´e dita amb´ıgua, n˜ao a linguagem que ela gera nem as senten¸cas para as quais haja mais de uma AD. Afinal, podem haver outras GLCs equivalentes a uma GLC amb´ıgua que n˜ao sejam amb´ıguas.
Exemplos de gram´aticas n˜ao amb´ıguas s˜ao aquelas dos Exemplos 81, 82 e 84 da Se¸c˜ao 3.4.1. J´a a gram´atica do Exemplo 83 ´e amb´ıgua, como mostra o exemplo a seguir.
P 0 P 1 P 1 P 0 P λ λ λ P 0 P 1 P λ 0 P 1 P λ λ
Figura 3.17 Duas ´arvores de deriva¸c˜ao de 0101.
P → 0P 1P | 1P 0P | λ
As duas ADs de 0101 apresentadas na Figura 3.17 demonstram que tal GLC ´e amb´ıgua. `
A ´arvore da esquerda corresponde, entre outras, a deriva¸c˜ao: P ⇒ 0P 1P (regra P → 0P 1P ) ⇒ 01P 0P 1P (regra P → 1P 0P ) ⇒ 010P 1P (regra P → λ) ⇒ 0101P (regra P → λ) ⇒ 0101 (regra P → λ) `
A ´arvore da direita corresponde a seguinte deriva¸c˜ao, entre outras: P ⇒ 0P 1P (regra P → 0P 1P )
⇒ 01P (regra P → λ) ⇒ 010P 1P (regra P → 0P 1P ) ⇒ 0101P (regra P → λ) ⇒ 0101 (regra P → λ)
O pr´oximo exemplo apresenta uma gram´atica amb´ıgua que gera a linguagem de express˜oes aritm´eticas, gerada tamb´em pela gram´atica n˜ao amb´ıgua do Exemplo 84.
Exemplo 87 Seja a gram´atica G = ({E}, {a, +, ∗, (, )}, R, E), para as express˜oes arit-m´eticas, em que R consta das regras:
E → E + E | E ∗ E | (E) | a
Essa gram´atica ´e amb´ıgua, j´a que existem duas ADs da palavra a+a*a, as quais est˜ao mostradas na Figura 3.18. `A ´arvore da esquerda corresponde, entre outras, a deriva¸c˜ao:
E E + E a E * E a a E E * E E + E a a a
Figura 3.18 Duas ´arvores de deriva¸c˜ao de a+a*a.
E ⇒ E + E (regra E → E + E) ⇒ a + E (regra E → a) ⇒ a+ E ∗ E (regra E → E ∗ E) ⇒ a + a ∗ E (regra E → a) ⇒ a + a ∗ a (regra E → a). `
A ´arvore da direita corresponde a seguinte deriva¸c˜ao, entre outras: E ⇒ E ∗ E (regra E → E ∗ E)
⇒ E + E ∗ E (regra E → E + E) ⇒ a + E ∗ E (regra E → a) ⇒ a + a ∗ E (regra E → a) ⇒ a + a ∗ a (regra E → a).
Como j´a foi dito anteriormente, em geral, o significado ´e associado a uma palavra de acordo com a AD obtida. Por exemplo, a AD do lado esquerdo da Figura 3.18 leva `a interpreta¸c˜ao de a+a*a como a soma de um elemento com o produto de dois elementos, isto ´e, a+(a∗a), enquanto a AD do lado direito da mesma figura leva `a interpreta¸c˜ao de a+a*acomo o produto da soma de dois elementos com um elemento, ou seja, (a + a) ∗ a.
Entre as deriva¸c˜oes correspondentes a uma AD, existem duas de particular interesse: as deriva¸c˜oes mais `a esquerda e as deriva¸c˜oes mais `a direita.
Defini¸c˜ao 45 Uma deriva¸c˜ao ´e dita mais `a esquerda (DME ) se em cada passo ´e
ex-pandida a vari´avel mais `a esquerda. E ´e dita mais `a direita (DMD ) se em cada passo
´
e expandida a vari´avel mais `a direita. Para enfatizar que uma deriva¸c˜ao ´e mais `a esquerda, pode-se usar “⇒e” em vez de “⇒” e, para uma deriva¸c˜ao mais `a direita, pode-se utilizar “⇒d”.
Existe uma ´unica DME e uma ´unica DMD correspondentes a uma AD: para obter a DME a partir de uma AD, basta ir gerando os passos de deriva¸c˜ao `a medida em que se percorre a AD visitando primeiro as sub´arvores `a esquerda, antes de visitar as sub´arvores `a direita; para obter a DMD, visita-se primeiro as sub´arvores `a direita. Assim sendo, pode-se dizer que:
• uma GLC ´e amb´ıgua se, e somente se, existe mais de uma DME para alguma senten¸ca que ela gere;
• uma GLC ´e amb´ıgua se, e somente se, existe mais de uma DMD para alguma senten¸ca que ela gere.
Exemplo 88 No Exemplo 87 foram mostradas as duas DMEs que correspondem `as ADs da Figura 3.18. As duas DMDs que correspondem `as mesmas ADs s˜ao, para a primeira AD: E ⇒d E + E (regra E → E + E) ⇒d E + E ∗ E (regra E → E ∗ E) ⇒d E + E∗ a (regra E → a) ⇒d E + a ∗ a (regra E → a) ⇒d a+ a ∗ a (regra E → a)
e para a segunda AD:
E ⇒d E ∗ E (regra E → E ∗ E)
⇒d E ∗ a (regra E → a)
⇒d E + E ∗ a (regra E → E + E)
⇒d E + a ∗ a (regra E → a)
⇒d a+ a ∗ a (regra E → a).
H´a linguagens livres do contexto (LLCs) para as quais existem apenas gram´aticas amb´ıguas. Essas linguagens s˜ao denominadas linguagens inerentemente amb´ıguas. Um exemplo de linguagem inerentemente amb´ıgua ´e {ambnck| m = n ou n = k}. Pode-se
mostrar que qualquer GLC que gere tal linguagem ter´a mais de uma AD para palavras da forma anbncn.
A detec¸c˜ao e remo¸c˜ao de ambiguidade em GLCs ´e muito importante, por exemplo, como um passo pr´evio ao uso de uma gram´atica para a gera¸c˜ao de um compilador para uma linguagem de programa¸c˜ao. Na pr´oxima se¸c˜ao ser˜ao vistas algumas t´ecnicas de modifica¸c˜ao de GLCs, que n˜ao alteram a linguagem gerada. No entanto, infelizmente, o problema de determinar se uma GLC arbitr´aria ´e amb´ıgua ´e indecid´ıvel, como ser´a mostrado no Cap´ıtulo 5.
Existem dois tipos b´asicos de analisadores sint´aticos gerados5 a partir de GLCs: o bottom-up e o top-down. Um analisador bottom-up parte do programa, lendo-o da
5
Um analisador sint´atico ´e um programa cujo objetivo principal ´e determinar se um programa est´a sintaticamente correto.
esquerda para a direita, e aplica as regras de forma invertida, construindo a AD da fronteira para a raiz, ou seja, bottom-up; a deriva¸c˜ao considerada durante o processo ´e uma DMD (obtida de tr´as para a frente). Por outro lado, um analisador top-down parte do s´ımbolo de partida da GLC e constr´oi a AD da raiz em dire¸c˜ao `a fronteira, ou seja, top-down; a deriva¸c˜ao considerada ´e uma DME. Os detalhes estariam fora do escopo deste texto, e podem ser encontrados em qualquer livro-texto sobre constru¸c˜ao de compiladores. De qualquer forma, fica evidenciada a importˆancia dos trˆes conceitos do ponto de vista pr´atico: AD, DME e DMD.
A mesma linguagem pode ser gerada por in´umeras gram´aticas. Algumas gram´aticas podem ser mais adequadas que outras, dependendo do contexto para o qual elas foram projetadas. Assim, ´e importante saber algumas t´ecnicas de manipula¸c˜ao de GLCs de forma a obter GLCs equivalentes, mas com a presen¸ca ou ausˆencia de certa(s) carac-ter´ıstica(s) relevante(s) para determinada aplica¸c˜ao. Em particular, existem algumas
formas normais que s˜ao apropriadas em diversas situa¸c˜oes, como quando se pretende mostrar que certa propriedade vale para todas as linguagens livres do contexto. Na pr´oxima se¸c˜ao, ser˜ao apresentadas algumas t´ecnicas de manipula¸c˜ao de GLCs, assim como duas formas normais importantes.
3.4.3 Manipula¸c˜ao de gram´aticas e formas normais
A detec¸c˜ao de vari´aveis que nunca participam de deriva¸c˜oes de palavras da linguagem gerada por uma GLC, as chamadas vari´aveis in´uteis, ´e importante por v´arios motivos. Por exemplo, em gram´aticas grandes, como as de linguagens de programa¸c˜ao, pode acontecer de se esquecer de definir as regras relativas a uma vari´avel; ou, ent˜ao, uma vari´avel, apesar de ter suas regras j´a definidas, pode n˜ao ter sido utilizada ainda na forma¸c˜ao de novas regras. Ambos os tipos de vari´aveis in´uteis podem ser detectados. Ap´os a detec¸c˜ao das vari´aveis in´uteis, pode-se acrescentar novas regras para prever a defini¸c˜ao ou uso das vari´aveis. Ou ent˜ao, caso uma vari´avel seja efetivamente in´util, deve-se eliminar todas as regras que possuem alguma ocorrˆencia da mesma.
Segue uma defini¸c˜ao precisa de vari´avel ´util, assim como algoritmos para a detec¸c˜ao de vari´aveis in´uteis e um m´etodo para eliminar todas as vari´aveis in´uteis de uma GLC. Defini¸c˜ao 46 Seja uma GLC G = (V, Σ, R, P ). Uma vari´avel X ∈ V ´e dita ser uma vari´avel ´util se, e somente se, existem u, v ∈ (V ∪ Σ)∗ ew ∈ Σ∗ tais que:
P ⇒ uXv∗ ⇒ w.∗
Observe que, pela Defini¸c˜ao 46, para a vari´avel X ser ´util ´e necess´ario, n˜ao apenas que existam u e v tais que P ⇒ uXv, mas tamb´em que, para algum u e algum v, tais∗ que P ⇒ uXv, se tenha que uXv∗ ⇒ w para algum w ∈ Σ∗ ∗.
Exemplo 89 Seja a gram´atica ({P, A, B, C}, {a, b, c}, R, P ), em que R cont´em as regras: P → AB | a
C → c
• C ´e in´util: n˜ao existem u e v tais que P ⇒ uCv;∗ • A ´e in´util: n˜ao existe w ∈ Σ∗ tal que A⇒ w;∗
• B ´e in´util: P ⇒ uBv apenas para u = A e v = λ, e n˜ao existe w ∈ Σ∗ ∗ tal que AB⇒ w (pois n˜ao existe w ∈ Σ∗ ∗ tal que A⇒ w).∗
Eliminando-se essas vari´aveis e todas as regras que as referenciam, al´em dos termi-nais b e c que n˜ao ocorrem em nenhuma regra retida,6 tem-se a gram´atica equivalente
({P }, {a}, {P → a}, P ).
O m´etodo de elimina¸c˜ao de vari´aveis in´uteis consta de duas etapas. Na primeira, elimina-se as vari´aveis a partir das quais n˜ao ´e poss´ıvel gerar senten¸cas (como a vari´avel A do exemplo anterior). Ap´os tal elimina¸c˜ao, na segunda etapa elimina-se as vari´aveis que n˜ao ocorram em formas sentenciais deriv´aveis a partir do s´ımbolo de partida (como a vari´avel C do exemplo). A defini¸c˜ao a seguir, d´a o conjunto de vari´aveis a partir das quais ´e poss´ıvel gerar senten¸cas. Usa-se a nota¸c˜ao vars(w) para designar o conjunto das vari´aveis que ocorrem na palavra w.
Defini¸c˜ao 47 O conjunto SG= {X ∈ V | X ∗
⇒ w para algum w ∈ Σ∗}, para uma GLC
G = (V, Σ, R, P ), pode ser assim definido recursivamente: • X ∈ SG, se existe X → w ∈ R tal que w ∈ Σ∗;
• se X → w ∈ R e vars(w) ⊆ SG, ent˜aoX ∈ SG.
A pr´oxima defini¸c˜ao mostra como obter o conjunto das vari´aveis que ocorrem em formas sentenciais deriv´aveis em uma GLC.
Defini¸c˜ao 48 O conjunto AG = {X ∈ V | P ∗
⇒ uXv para algum u, v ∈ (V ∪Σ)∗}, para uma GLCG = (V, Σ, R, P ), pode ser assim definido recursivamente:
• P ∈ AG;
• se X → w ∈ R e X ∈ AG, ent˜ao vars(w) ⊆ AG.
Vers˜oes procedurais de ambas as defini¸c˜oes, 47 e 48, est˜ao mostradas na Figura 3.19.
M´etodo 14 Elimina¸c˜ao de vari´aveis in´uteis
Considere uma GLC G = (V, Σ, R, P ). A partir de G, obt´em-se uma GLC equivalente sem vari´aveis in´uteis assim:
6
Pode-se dizer que tais terminais s˜ao in´uteis, visto que n˜ao s˜ao usados para formar palavras da linguagem gerada.
Entrada: uma GLC G = (V, Σ, R, P ). Sa´ıda: SG= {X ∈ V | X⇒ w para w ∈ Σ∗ ∗}. SG← ∅; repita N← {X ∈ V − SG| X → w ∈ R e vars(w) ⊆ SG}; SG← SG∪ N at´eN= ∅; retorne SG.
(a) Produzem senten¸cas
Entrada: uma GLC G = (V, Σ, R, P ). Sa´ıda: AG= {X ∈ V | P ⇒ w e X ∈ vars(w)}.∗ AG← {P }; repita N← {X ∈ V − AG| Y → w para Y ∈ AG e X ∈ vars(w)}; AG← AG∪ N at´eN= ∅; retorne AG.
(b) Alcan¸c´aveis a partir de P Figura 3.19 Algoritmos para achar vari´aveis ´uteis.
1. Obtenha G′ = (SG∪ {P }, Σ, R′, P ), em que R′= {X → w ∈ R | vars(w) ⊆ SG}.
2. Obtenha G′′ = (AG′, Σ, R′′, P ), em que R′′ = {X →∈ R′| X ∈ AG′}.
Note-se, em particular, que L(G) = ∅ se e somente se P 6∈ SG, e que, mesmo que seja
in´util, P ´e preservado nas GLCs G′ e G′′constru´ıdas pelo M´etodo 14. Alternativamente
a Σ, pode-se considerar como alfabeto de G′′o conjunto daqueles terminais que ocorrem em regras de R′′, desde que se cuide para que Σ tenha no m´ınimo um s´ımbolo se R′′= ∅. A nota¸c˜ao ⇒G, sendo G uma gram´atica, ser´a usada a seguir para informar que a
deriva¸c˜ao est´a sendo tomada com rela¸c˜ao `a gram´atica G.
Teorema 19 Seja uma GLC G tal que L(G) 6= ∅. Existe uma GLC, equivalente a G,
sem vari´aveis in´uteis.
Prova
Sejam G, G′ e G′′ como delineados no m´etodo descrito.
Inicialmente, veja que L(G′) = L(G), pois apenas as regras de G cujas vari´aveis X
s˜ao tais que X ⇒ w, para algum w ∈ Σ∗ ∗, podem contribuir para a gera¸c˜ao de alguma
palavra de L(G); e G′ cont´em exatamente essas regras. Analogamente, L(G′′) = L(G′). Resta ent˜ao mostrar que G′′ n˜ao possui vari´aveis in´uteis, ou seja, que todas as suas vari´aveis s˜ao ´uteis. Para isso, seja uma vari´avel arbitr´aria X ∈ V′′. Em primeiro
lugar, tem-se que P ⇒∗G′′ uXv, por constru¸c˜ao de R′′. E para qualquer uXv tal que
P ⇒∗G′′ uXv, tem-se que uXv
∗
⇒G′′ w e w ∈ Σ∗, pois todas as vari´aveis Y da forma
sentencial uXv s˜ao tais que Y ⇒ y e y ∈ Σ∗ ∗; isso porque as vari´aveis de R′ tˆem essa
propriedade por constru¸c˜ao, e ela ´e preservada na constru¸c˜ao de R′′. Esse ´ultimo fato ´e mostrado a seguir. Ao ser eliminada uma vari´avel Z de V′, se Y ⇒ uZv, ent˜ao n˜ao∗ podem existir r e s tais que P ⇒ rY s; caso contr´ario, ter-se-ia que P∗ ⇒ rY s∗ ⇒ ruZvs,∗ e Z n˜ao seria eliminada de V′. Portanto, se Y ⇒ uZv, Y ´e tamb´em eliminada. Caso∗ contr´ario, a elimina¸c˜ao de Z n˜ao altera o fato de que Y ⇒ w para algum w ∈ Σ∗ ∗ .
Segue um exemplo de aplica¸c˜ao do m´etodo de elimina¸c˜ao de vari´aveis in´uteis. Deve-se notar que o Algoritmo 3.19a deve Deve-ser aplicado antes do Algoritmo 3.19b.
Exemplo 90 Seja a gram´atica G = ({A, B, C, D, E, F }, {0, 1}, R, A}), em que R cont´em as regras: A → ABC | AEF | BD B → B0 | 0 C → 0C | EB D → 1D | 1 E → BE F → 1F 1 | 1
Primeiro, determina-se SG = {B, D, F, A}. De acordo com o m´etodo descrito, R′
consta das regras: A → BD B → B0 | 0 D → 1D | 1 F → 1F 1 | 1
Agora determina-se AG′ = {A, B, D}. Pelo m´etodo descrito, R′′ cont´em apenas as
regras:
A → BD B → B0 | 0 D → 1D | 1
Durante a concep¸c˜ao de uma gram´atica, o projetista pode deparar com a necessidade de modificar uma ou mais regras, sem alterar a linguagem gerada. Inicialmente, ser´a mostrado como eliminar uma regra X → w, em que X n˜ao ´e a vari´avel de partida, usando-se o expediente de “simular” a aplica¸c˜ao da mesma em todos os contextos poss´ıveis: para cada ocorrˆencia de X do lado direito de cada regra, prevˆe-se o caso em que X ´e substitu´ıda por w e o caso em que n˜ao o ´e. Com esse expediente, consegue-se produzir algumas deriva¸c˜oes mais curtas, `a custa do aumento do n´umero de regras da gram´atica.
M´etodo 15 Eliminando uma regra
Sejam uma GLC G = (V, Σ, R, P ) e X → w ∈ R em que X 6= P . Uma GLC equivalente sem a regra X → w seria G′ = (V, Σ, R′, P ) em que R′ ´e constitu´ıdo de:
1. cada regra Y → z ∈ R − {X → w} tal que X 6∈ vars(z); e
2. cada regra Y → x0γ1x1γ2x2. . . γnxn, em que cada γj pode ser X ou w, para cada
Y → x0Xx1Xx2. . . Xxn ∈ R com n > 0 ocorrˆencias de X e X 6∈ vars(xi) para
0 ≤ i ≤ n. Exce¸c˜ao: no caso em que Y = X, apenas X → x0Xx1Xx2. . . Xxn
Y B1 Bp X C1 Cq A1 An · · · · △ · · · △ △ · · · △ △ · · · △ (a) Antes Y B1 Bp A1 An C1 Cq · · · · △ · · · △ △ · · · △ △ · · · △ (b) Depois
Figura 3.20 Transforma¸c˜ao entre ADs induzida por remo¸c˜ao de regra.
Teorema 20 As GLCs G e G′, em queG′ ´e obtida como mostrado no M´etodo 15, s˜ao equivalentes.
Prova
N˜ao ser´a feita uma demonstra¸c˜ao rigorosa desse teorema, mas uma argumenta¸c˜ao relati-vamente precisa e clara, utilizando o conceito de ´arvore de deriva¸c˜ao (AD) desenvolvido na Se¸c˜ao 3.4.2. Uma GLC G gera uma palavra w se, e somente se, existe uma AD de w. Ser´a mostrado, ent˜ao, como transformar uma AD de w em G em uma AD de w em G′, e vice-versa. Seja, ent˜ao a regra X → w eliminada de G, com w = A1A2. . . An, em que
Ai∈ V ∪ Σ, e seja uma regra da forma Y → B1. . . BpXC1. . . Cq, com Bi, Cj ∈ V ∪ Σ
(note que cada Bi e Cj pode ser ou n˜ao X). Tendo em vista como G′ ´e obtida, uma
AD de w em G pode ser transformada em uma AD de w em G′ substituindo-se toda
sub´arvore da forma exposta na Figura 3.20a pela sub´arvore exibida na Figura 3.20b. Em palavras, para todo v´ertice vX de r´otulo X, filho de vY, de r´otulo Y , e cujos filhos
sejam (nesta ordem) vA1, vA2, . . . , vAn, com r´otulos A1, A2, . . . , An,
1. eliminar o v´ertice vX; e
2. colocar os v´ertices vA1, vA2, . . . , vAn (nesta ordem) como filhos de vY, entre os
v´ertices vBp e vC1.
Essa transforma¸c˜ao, assim como a inversa, ´e poss´ıvel, visto que X 6= P . Nela, a sub´arvore `a esquerda ´e substitu´ıda pela sub´arvore `a direita (ou vice-versa).
O m´etodo delineado acima ser´a exemplificado a seguir. Observe que, para se elimi-nar uma regra X → w, cada regra com n ocorrˆencias de X no seu lado direito d´a origem a at´e 2nregras: para cada ocorrˆencia, considera-se o caso em que ela ´e substitu´ıda por
w (aplica¸c˜ao da regra X → w) e o caso em que n˜ao o ´e (prevendo os casos de aplica¸c˜oes de outras regras X).
Exemplo 91 Seja a gram´atica G = ({P, A, B}, {a, b, c}, R, P ), em que R cont´em as regras:
P → ABA A → aA | a B → bBc | λ
que gera a linguagem {a}∗{bncn| n ≥ 0}{a}∗. Seja o problema de eliminar a regra
A → a. A regra P → ABA d´a origem a quatro regras: P → ABA | ABa | aBA | aBa e a regra A → aA resulta em duas regras:
A → aA | aa
Assim, a gram´atica resultante ´e G′ = ({P, A, B}, {a, b, c}, R′, P ), em que R′ cont´em as regras:
P → ABA | ABa | aBA | aBa A → aA | aa
B → bBc | λ
Note que o n´umero de regras aumentou, mas as deriva¸c˜oes propiciadas s˜ao mais curtas. Por exemplo, aa tem a seguinte deriva¸c˜ao em G:
P ⇒ ABA (regra P → ABA) ⇒ aBA (regra A → a) ⇒ aA (regra B → λ) ⇒ aa (regra A → a).
E a mesma palavra tem a seguinte deriva¸c˜ao em G′: P ⇒ aBa (regra P → aBa)
⇒ aa (regra B → λ).
Uma GLC em uma certa forma normal admite poucos formatos de regras, por´em sem alterar o poder descritivo: para qualquer LLC existir´a uma GLC equivalente na formal normal considerada. Com isto, elas facilitam demonstra¸c˜oes relativas a proprie-dades de LLCs, e, por propiciarem ´arvores de deriva¸c˜ao com estrutura uniforme, podem servir de base para constru¸c˜ao de analisadores sint´aticos.
Existem duas formas normais especialmente importantes para GLCs: as formas normais de Chomsky e de Greibach. Como visto, as restri¸c˜oes feitas `as regras de uma gram´atica para torn´a-la uma gram´atica regular restringem a classe de linguagens que podem ser descritas `a das linguagens regulares. Uma maneira de se tentar chegar a uma forma normal para GLCs ´e considerar: que modifica¸c˜oes m´ınimas se poderia fazer aos formatos de regras de gram´aticas regulares de forma a conseguir o poder de gerar qualquer LLC? Ora, uma ideia ´e simplesmente “generalizar” o formato de regra X → aY de gram´aticas regulares para permitir uma vari´avel no lugar do terminal a.