Anda di halaman 1dari 38

Formateador y Analizador de textos

Daniel Montoya Ramos Eva Mara Garca Garca Loli Burgueo Caballero

ndice
Formateador Analizador

Analizador mondico

Formateador de textos

Analizador de textos

Analizador de textos

Introduccin
Show

Read

Analizador de textos

Analizador que reconoce una lista de uno o ms enteros


Operadores (combinadores) Metasmbolo definicin (::=) Metasmbolo alternativa (|) Metasmbolo repeticin ({}0) Metasmbolo repeticin no vaca ({}1) Metasmbolo opcin ([]) Metasmbolo agrupacin (())

Analizador de textos

Analizador que reconoce una lista de uno o ms enteros


Gramtica Dgito ::= 0|1|2|3|4|5|6|7|8|9 NumNatural ::= {Dgito}1 NumEntero ::= [+|-] NumNatural ListaEnteros ::= [ Enumeracin ] Enumeracin ::= NumEntero {, NumEntero}0

Analizador de textos

ReadS a
Tipo polimrfico para analizadores que

devuelven valores de tipo a type ReadS a = String -> [(a, String)] Devolver un par donde:
La primera componente ser un valor del tipo a. La segunda ser de tipo String y se corresponder con el valor de la cadena de salida.
8

Analizador de textos
Primer analizador: xito :: a -> ReadS a xito x = \s -> [(x, s)] Toma un argumento, no consume ningn carcter y devuelve ese mismo argumento. Segundo analizador: psilon :: ReadS () psilon = xito () No toma argumentos y devuelve siempre el mismo, (). Tampoco consume caracteres de la entrada. Tercer analizador: fallo :: ReadS a fallo = \s -> [] Falla siempre.

Analizador de textos

rCHar

rChar :: Char -> ReadS Char rChar c = \s -> case s of [] -> [] x:xs -> if c == x then [(x,xs)] else []
Toma un carcter como argumento Tiene xito si la cadena de entrada comienza

por ese carcter y en ese caso lo consume

10

Analizador de textos
rSat rSat :: (Char -> Bool) -> ReadS Char rSat p = \s -> case s of [] -> [] x:xs -> if p x then [(x,xs)] else []

Ms general que rChar Recibe como argumento una condicin

Tiene xito si el primer carcter de la cadena de

entrada cumple la condicin y en ese caso lo consume.


11

Analizador de textos

Metasmbolo alternativa. Analizador -+-

infixl 5 -+(-+-) :: ReadS a -> ReadS a -> ReadS a p1 -+- p2 = \s -> p1 s ++ p2 s


El analizador p1 -+- p2 tendr xito si lo tiene

p1, p2 o ambos Devolver en la lista solucin el resultado de aplicar p1 y el de aplicar p2


12

Analizador de textos
Analizador >>> infixr 6 >>> (>>>) :: ReadS a -> (a -> ReadS b) -> ReadS b p >>> f = \s -> [ (y,s2) | (x,s1) <- p s, let p2 = f x, (y,s2) <- p2 s1 ]

Argumentos: un analizador y una funcin. Ejemplo: funcin rAB rAB :: ReadS (Char, Char) rAB = rSat isUpper >>> (\x -> rSat isUpper >>> (\y -> xito (x,y))) solo tiene xito si en la entrada hay dos caracteres mayscula consecutivos y en ese caso los devuelve.

13

Analizador de textos

Metasmbolo repeticin (rep1) rep1 :: ReadS a -> ReadS [a]


Aplica el analizador p una o ms veces a la

entrada y devuelve el resultado en una lista

Metasmbolo repeticin no vaca (rep0) rep0 :: ReadS a -> ReadS [a]


Idem pero tambin permite aplicarla cero

veces

14

Analizador de textos

Reconocer nmeros naturales rNumNatural :: ReadS Integer


Devuelve un analizador de enteros

Usamos los combinadores definidos y

pasamos el valor a Int El resultado deseado es el primero => definimos una funcin primero y la aplicamos al resultado anterior

15

Analizador de textos

Metasmbolo de opcin (?) (?) :: ReadS a -> a -> ReadS a


Argumentos: 1. Primer argumento: Analizador p 2. Segundo argumento Si p tiene xito sobre la cadena de

entrada devuelve dicho resultado Si p falla devuelve el segundo argumento.


16

Analizador de textos

Reconocer nmeros enteros


Ideas generales (rChar '+' -+- rChar '-') <cadena>
1. <cadena> empieza por + 2. <cadena> empieza por - 3. <cadena> empieza por un dgito

((rChar '+' -+- rChar '-') ? +) <cadena>


Problema resuelto Queda reconocer el numero natural

17

Analizador de textos

Lista de nmeros enteros rListaEnteros :: ReadS [Integer]


Devuelve un analizador de enteros Es fcil de definir a partir de los operadores

anteriores.

18

Analizadores Mondicos

19

Representacin

data Analiz a = AN (Estado -> [(a,Estado)]) type Estado = String

20

Funciones

Aplicar un analizador a una cadena de entrada devolviendo los posibles anlisis


aplica :: Analiz a -> String -> [(a,Estado)] aplica (AN p) ent = p ent

Analizador elemental
elemento :: Analiz Char elemento = AN (\ent -> case ent of

[] -> [] (x:xs) -> [(x,xs)])


21

Secuenciacin
instance Monad Analiz where -- return :: a -> Analiz a return v = AN (\ent -> [(v,ent)]) -- (>>=) :: Analiz a -> (a -> Analiz b) -> Analiz b (AN p) >>= k = AN (\ent -> concat [aplica (k v) sal | (v,sal) <- p ent])

22

Propiedades de las Mnadas

Elemento neutro de la secuenciacin


(>>=f).return (>>= return)

=f = id

Asociatividad de la secuenciacin
(>>=g).(>>=f)

= (>>=((>>=g).f))

23

Alternancia
instance MonadPlus Analiz where mplus (AN p) (AN q) = AN (\ent -> p ent ++ q ent) mzero = AN (\ent -> [] )

(!+) :: Analiz a -> Analiz a -> Analiz a (!+) = mplus

24

Ejemplo: Analizador que lee uno o dos elementos


unoODosElementos :: Analiz String unoODosElementos = elementoS !+ dosElementos Main> aplica unoODosElementos "" [] :: [([Char],Estado)] Main> aplica unoODosElementos "h" [("h","")] :: [([Char],Estado)] Main> aplica unoODosElementos "hola" [("h","ola"),("ho","la")] :: [([Char],Estado)]

25

Propiedades de la alternancia
Asociativa (m !+ n) !+ o = m !+ (n!+o) Distributiva (m !+ n) >>= o = (m>>=o) !+ (n!+o) Elemento neutro mzero !+ m = m m!+ mzero = m

26

Filtros

(!>) :: Analiz a -> (a -> Bool) -> Analiz a


k !> p = do a <- k if p a then return a else mzero

27

Ejemplos: analizadores de letra, dgito o ambos


letra :: Analiz Char letra = elemento !> isAlpha dgito :: Analiz Char dgito = elemento !> isDigit letraODgito = letra !+ dgito literal :: Char -> Analiz Char literal c = elemento !> (== c) Main> aplica letra "hola" [('h',"ola")] :: [(Char,Estado)] Main> aplica letra "5hola" [] :: [(Char,Estado)] Main> aplica dgito "5hola" [('5',"hola")] :: [(Char,Estado)]

28

Iteracin
iter :: Analiz a -> Analiz [a] iter m = do x <- m xs <- iter m return (x:xs) !+ return []

29

Ejemplo: analizar un nmero


nmero :: Analiz Int nmero = do a <- dgito x <- iter dgito return (aInt (a:x)) where chrAInt :: Char -> Int chrAInt c = ord c - ord '0' aInt :: [Char] -> Int aInt = foldl1 (\x y -> 10*x + y) . map chrAInt Main> aplica nmero "123letras" [(123,"letras"),(12,"3letras"),(1,"23letras")] :: [(Int,Estado)]
30

Eleccin parcial
(!*) :: Analiz a -> Analiz a -> Analiz a m !* n = AN (\ent -> let as = aplica m ent in if (null as) then aplica n ent else as)

31

Ejemplo: analizador ms largo, nmero ms largo


reiter :: Analiz a -> Analiz [a] reiter m = do a <- m x <- reiter m return (a:x) !* return [] nmero' = do a <- dgito x <- reiter dgito return (aInt (a:x)) where chrAInt :: Char -> Int chrAInt c = ord c - ord '0' aInt :: [Char] -> Int aInt = foldl1 (\x y -> 10*x + y) . map chrAInt Main> aplica nmero' "123letras" [(123,"letras")] :: [(Int,Estado)]

32

Ejemplo: leer cadena de espacios, token sin espacios


espacios :: Analiz String espacios = do a <- literal ' ' x <- reiter (literal ' ') return (a:x) !* return ""
token :: String -> Analiz String token xs = do _ <- espacios tk <- token' xs return tk where token' [] = return [] token' (x:xs)= do c <- elemento !> (== x) cs <- token' xs return (c:cs) Main> aplica (token "let") " let x=1 in 2*x" [("let"," x=1 in 2*x")] :: [([Char],Estado)]

33

Un analizador para trminos


Gramtica -- term ::= constante -| ( term + term ) -| ( term / term ) data Term = Const Int | Term :/: Term | Term :+: Term deriving Show anaConst :: Analiz Term anaConst = do a <- nmero return (Const a)
34

Un analizador para trminos


anaSum' :: Analiz Term anaSum' = do _ <- literal '(' u <- term' _ <- literal '+' v <- term' _ <- literal ')' return (u :+: v) anaDiv' :: Analiz Term anaDiv' = do _ <- literal '(' u <- term' _ <- literal '/' v <- term' _ <- literal ')' return (u :/: v)

35

Un analizador para trminos

Analizador ms genrico con delimitadores

paren :: Analiz a -> Analiz b -> Analiz c -> Analiz b paren abre m cierra = do abre x <- m cierra return x
anaSum = paren (literal '(') (do { u <- term ; literal '+' ; v <- term ; return (u :+: v)}) (literal ')') anaDiv = paren (literal '(') (do { u <- term ; literal '/' ; v <- term ; return (u :/: v)}) (literal ')')

36

Un analizador para trminos


anaOp :: Analiz (Term -> Term -> Term) anaOp = (do {literal '+'; return (:+:)}) !* (do {literal '/'; return (:/:)}) anaExpr :: Analiz Term anaExpr = do u <- term o <- anaOp v <- term return (o u v)

anaSD :: Analiz Term anaSD = paren (literal '(') anaExpr (literal ')')
term = anaConst !+ anaSD
37

Ruegos y preguntas

38

Anda mungkin juga menyukai