-
Notifications
You must be signed in to change notification settings - Fork 0
/
Parser.hs
65 lines (49 loc) · 1.59 KB
/
Parser.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
module Parser where
import Control.Monad
import GHC.Base hiding ((<|>))
-- | Parser type
newtype Parser a = P {runP :: String -> [(a,String)]}
instance Functor Parser where
fmap f p = P $ \cs -> [(f a,cs') | (a,cs') <- runP p cs]
instance Applicative Parser where
pure a = P (\cs -> [(a,cs)])
-- (<*>) :: Parser (a -> b) -> Parser a -> Parser b
(P p) <*> (P q) = P $ \cs -> [ (f a, cs'') | (f , cs') <- p cs
, (a , cs'') <- q cs']
instance Monad Parser where
return a = P $ \cs -> [(a,cs)]
(P p) >>= f = P $ \cs -> concat [runP (f a) cs' | (a,cs') <- p cs]
-- | Parsers primitivos
pFail :: Parser a
pFail = P $ \cs -> []
-- no determinista
(<|>) :: Parser a -> Parser a -> Parser a
(P p) <|> (P q) = P $ \cs -> p cs ++ q cs
-- determinista
(<||>) :: Parser a -> Parser a -> Parser a
(P p) <||> (P q) = P $ \cs -> case p cs ++ q cs of
[] -> []
(x:xs) -> [x]
item :: Parser Char
item = P $ \cs -> case cs of
"" -> []
(c:cs) -> [(c,cs)]
pSat :: (Char -> Bool) -> Parser Char
pSat p = do c <- item
if p c then return c
else pFail
pSym :: Char -> Parser Char
pSym c = pSat (== c)
-- | recursión
-- | cero o más veces p
pList :: Parser a -> Parser [a]
pList p = do a <- p
as <- pList p
return (a:as)
<|>
return []
-- | una o más veces p
pList1 :: Parser a -> Parser [a]
pList1 p = do a <- p
as <- pList p
return (a:as)