Você está na página 1de 8

Processamento de Linguagens e Compiladores LMCC, Universidade do Minho

Ano lectivo 2005/2006 Joo Saraiva a Ficha Terico-Prtica No 8 o a

Este texto est escrito em literate Haskell. Isto , pode ser interpretado como um doa e A X ou como um puro programa na linguagem Haskell. Responda `s perguntas cumento L TE a sobre Haskell neste prprio cheiro para assim produzir o programa e a sua documentao. o ca

Propriedades de Gramticas Independentes do Cona texto

Nesta cha terico-prtica apresentam-se funes que denem propriedades de s o a co mbolos no-terminais, produes e das prprias gramticas independentes do contexto. Estas a co o a funes so expressas em Haskell. Para tal dene-se o mdulo CfgProp. Nesta cha co a o terico-prtica apresentam-se funes que denem propriedades de s o a co mbolos no-terminais, a produes e das prprias gramticas independentes do contexto. Estas funes so expresco o a co a sas em Haskell. Para tal dene-se o mdulo CfgProp. o Soluo ca --- Mdulo de Propriedades de Gramticas Independentes do Contexto o a --- Processamento de Linguagens e Compiladores -- 2005/2006 -module CfgProp where import List import Cfg

1.1

Gramticas Amb a guas

Uma gramtica G = (T, N, S, P ) diz-se amb a gua se existirem duas sequncias de derivao e ca diferentes para uma mesma frase T . A ambiguidade surge na escolha da produo a ca usar durante o processo de re-escrita de um s mbolo no terminal. Isto , num dado passo a e o processo de re-escrita de um s mbolo no terminal existe mais do que uma produo a ca poss vel que conduz ` aceitao da frase. Logo existe ambiguidade em saber qual das a ca diferentes alternativas (caminhos) seguir. 1.1 Considere a seguinte gramtica independente de contexto Gexp = (T, N, S, P ), com: a T = {+, , , /, i, (, )}, N = {E}, S = E, P = { add : E E + E , sub : | E E , plus : | E E , div : | E /E , prio : | (E ) , numb : | i } em que i um smbolo pseudo-terminal que representa a classe dos nmeros inteiros. e u Responda `s seguintes perguntas. a 1. Prove que a gramtica Gexp ambgua. Utilize para tal uma sequncia de derivao a e e ca LR. 2. Prove que a gramtica Gexp ambgua. Utilize para tal uma sequncia de derivao a e e ca LL. 1.2 Considere a gramtica independente de contexto g4 escrita em Haskell e apresentada a a seguir. Responda `s seguinte perguntas. a 1. Prove que xzwzwzy L(g4 ) 2. A gramtica g4 ambgua? a e Soluo ca g 4 = Cfg [x, y, z, w] [X, Y, Z, W] X [("p0", X "xY") , ("p1", Y "y") , ("p1", Y "Zy") , ("p2", Z "zW") , ("p3", W "wZ") , ("p4", W "") ] 2

1.2

Gramticas No Amb a a guas

Uma gramtica independente do contexto diz-se no ambgua se para toda a frase da a a linguagem denida pela gramtica existir uma unica sequncia de derivao para essa frase. a e ca Neste caso no existe qualquer ambiguidade na escolha do caminho a seguir. Neste seco a ca apresentamos a denio formal de algumas funes sobre gramticas que nos ajudaro ca co a a posteriormente a provar que uma gramtica no amb a e a gua.

1.3

Funes F irst e F irstN co

A funo F irst calcula o conjunto de s ca mbolos que iniciam derivaes a partir de uma co sequncia de s e mbolos terminais e no terminais. A funo First de uma sequncia de a ca e s mbolos dene-se do seguinte modo: F irst : (N T ) 2T com F irst() denido por, para a T e X N : 1. Se = a ento F irst() = {a}; a 2. Se = A A 1 | | n i i F irst() =
1 i n

ento a

F irst(i ) ento a F irst(i )


1 i n

3. Se = A A 1 | | n i i F irst() = F irst( )

A funo F irstN determina o conjunto de s ca mbolos que iniciam derivaes a partir de co um s mbolo no terminal. A funo F irstN de um s a ca mbolo no terminal dene-se como: a F irstN : N 2T F irstN (X) : (Xi )P F irst(i ) 1.3 Considere de novo a gramtica gexp . Calcule os seguintes conjuntos: a 1. F irst(rhs(add)) 2. F irstN (E) 1.4 Considere de novo a gramtica g4 . Calcule os conjuntos F irstN de todos os smbolos a no terminais. a

A funo First escreve-se em Haskell seguindo directamente a sua denio formal. A ca ca funo Haskell f irst tem tipo: ca Soluo ca rst :: Eq sy Cfg sy -- grammar [sy ] -- sequence of symbols [sy ] -- First set Na denio da funo rst temos de ter o cuidado de no voltar a considerar um ca ca a s mbolo no terminal que j o tenha sido antes. Para tal usamos uma funo auxiliar rst a a ca que tem um parametro adicional onde so acumulados os s a mbolos j considerados. a Soluo ca rst g sy = nub $ rst g [ ] sy rst :: Eq sy Cfg sy -- grammar [sy ] -- accumulator: nonterminals visited so far [sy ] -- sequence of symbols [sy ] -- First set = [] rst g [ ] rst g v (h : t) | h is terminal g = [h ] |hv = rst g v t | nullable nt g h = (rst g (h : v ) t) union rst rhs g v h | otherwise = rst rhs g v h where rst rhs g v nt = concat $ map (rst g (nt : v )) (rhs nt g nt) A funo f irstN dene-se como um map da funo anterior pelos lados direitos das ca ca produes do s co mbolo dado. Soluo ca rstN :: Eq sy Cfg sy -- grammar sy -- nonterminal [sy ] -- First set rstN g nt = nub $ concat $ map (rst g) (rhs nt g nt) 1.5 Utilize as denies Haskell para conrmar os resultados do exerccio anterior. co

Funo F ollow ca

A funo F ollow de um s ca mbolo no terminal calcula o conjunto de s a mbolos terminais que se podem seguir a uma derivao a partir do s ca mbolo no terminal. A funo F ollow de a ca um s mbolo no terminal dene-se do seguinte modo: a F ollow : F ollow(X) : N 2T
(Y X)P

F irst() 4

se F ollow(Y ) se

2.1 Considere de novo as gramtica gexp e g4 . Calcule o conjunto de smbolos F ollow a para os s mbolos no terminais destas gramticas. a a 2.2 No clculo da funo Follow de um smbolo no terminal necessrio identicar a ca a e a primeiro o conjunto de produes onde o smbolo no terminal ocorre no lados direito e as co a sequncias de smbolos que se segue a cada ocorrncia. Escreva em Haskell as seguintes e e funes sobre o tipo Cfg: co 1. Funo rhs with nt que dado uma gramtica e um smbolo no terminal, calcula o ca a a conjunto de produes (sem nome) em que esse smbolo ocorre no lado direito. co 2. Funo suf f ices que dado um smbolo no terminal e uma produo devolve a lista ca a ca de sequncias de smbolos que seguem as ocorrncias do no terminal no lado direito e e a da produo dada. Note que um smbolo no terminal pode ocorrer mais do que uma ca a vez no lado direito de um produo. Associe a cada um dos elementos desta lista ca o lado esquerdo da produo onde o suxo ocorreu. Um exemplo de execuo desta ca ca funo apresenta-se a seguir. ca *CfgProp> suffices B (A |-> [B,C,B]) [(A,"CB"),(A,"")] 3. Funo rhs suf f ices que dado uma gramtica e um smbolo no terminal X devolve ca a a as sequncias de smbolos que seguem as ocorrncias de X nos lados direitos das e e produes de P . A estes suxos so tambm associados ao smbolo no terminal do co a e a lado esquerdo de P . Por exemplo, se executarmos esta funo sobre a gramtica g3 ca a o (denida na cha n 10) e o no terminal B temos: a *CfgProp> rhs_suffices g_3 B [(A,"CB"),(A,""),(B,"b"),(C,"")] Soluo ca rhs with nt :: Eq sy Cfg sy sy [[sy ]] rhs with nt g nt = lter (elem nt tail ) (map snd (prods g)) suces :: Eq sy sy [sy ] [(sy, [sy ])] suces nt (lhs : rhs) = rhs suces nt rhs nt where rhs suces nt [ ] = [] rhs suces nt (h : t) nt | h nt = (lhs, t) : rhs suces nt t nt | otherwise = rhs suces nt t nt rhs suces :: (Eq sy) Cfg sy sy [(sy, [sy ])] rhs suces g nt = concat $ map (suces nt) (rhs with nt g nt) A funo Follow escreve-se em Haskell seguindo de novo a sua denio formal. Porm, ca ca e e tal como na denio da funo rst e nullable, temos de ter o cuidado de manter uma ca ca 5

lista de s mbolos no terminais j considerados de modo ` denio da funo terminar. a a a ca ca O tipo da funo follow : ca e Soluo ca follow :: Eq sy Cfg sy -- grammar sy -- nonterminal [sy ] -- Follow set A funo escreve-se em Haskell da seguinte forma: ca Soluo ca follow g nt = nub $ follow g [ ] nt follow :: Eq sy Cfg sy [sy ] sy [sy ] follow g v nt | nt v = [] | otherwise = concat $ map (follow g (nt : v )) (rhs suces g nt) follow :: (Eq sy) Cfg sy [sy ] (sy, [sy ]) [sy ] follow g v (l , r ) | nullable g [ ] r = rst g r union follow g v l | otherwise = rst g r 2.3 Utilize a denio Haskell para vericar as solues do exerccio ??. ca co

Funo Lookahead ca

Como foi referido anteriormente, para uma gramtica ser no amb a a gua no pode existir a ambiguidade na escolha da produo a utilizar em cada passo da derivao de uma frase. ca ca Um modo de garantir que uma gramtica no possui ambiguidade na escolha da produo a a ca a utilizar, consiste no seguinte: sempre que se vai expandir um s mbolo no terminal A, a tenta-se olhar para a frente1 , de modo a determinar quais os s mbolos terminais que iniciam as vrias alternativas/produes de A. Caso estes in a co cios sejam dijuntos, ento no existe a a ambiguidade na escolha do lado direito, pelo qual A vai ser expandido. Formalmente, a funo que permite olhar para a frente, designada Lookahead, deneca se do seguinte modo: Lookahead : P 2T se F ollow(A) se

Lookahead(A ) : F irst() E a sua escrita em Soluo ca lookahead :: Eq Cfg sy - [sy ] -1

Haskell segue directamente a denio formal. ca sy grammar production

Na terminologia inglesa designa-se por Lookahead.

[sy ] -- Lookahead set lookahead g p | nullable g [ ] (rhs p) = nub $ rst g (rhs p) + follow g (lhs p) + | otherwise = nub $ rst g (rhs p) 3.1 Considere de novo as gramtica gexp e g4 . Calcule o conjunto de Lookaheads das a produes de ambas as gramticas. Utilize a denio da funo em Haskell para confrmar co a ca ca estes resultados. 3.2 Escreva em Haskell as seguintes funes sobre o tipo de dados Cfg: co 1. Funo lookaheadsn t que dado uma gramtica e um smbolo no terminal devolve ca a a o conjunto de lokaheads das produes que tem o smbolo no terminal como lado co a esquerdo. 2. Funo all lookaheads que dado uma gramtica devolve os lookaheads de todas as ca a produes. co Soluo ca all lookaheads g = map (lookahead g) (map snd (prods g)) lookaheads nt g nt = map (lookahead g) (prods nt g nt)

Condio LL(1) ca

Para garantir que no h ambiguidade na escolha da produo, denimos a condio LL(1). a a ca ca Uma gramtica G = (T, N, S, P ) satisfaz a condio LL(1) se a ca A1 ,A2 P : Lookahead(A 1 ) Lookahead(A 2 ) = Que se dene facilmente em Haskell do seguinte modo: Soluo ca ll 1 nt g nt = and (map ( [ ]) (intersects xs)) where xs = lookaheads nt g nt intersects [ ] = [] intersects (h : t) = (map (intersect h) t) + (intersects t) + ll 1 :: Eq sy Cfg sy Bool ll 1 g = and $ map (ll 1 nt g) (nonterminals g) 4.1 Utilizando a denio formal da condio LL(1) e a sua representao em Haskell, ca ca ca responda `s seguintes perguntas: a 1. Prove, utilizando a denio formal, que a gramtica gexp no LL(1). ca a a e 2. Prove, utilizando a denio formal, que a gramtica g4 LL(1). ca a e 7

3. Prove que a gramtica g4 no ambgua. a e a 4. Prove que a gramtica gexp ambgua. a e 5. Utilize a denio em Haskell para conrmar estes resultados. ca

Você também pode gostar