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
66
67
|
module ParserComb where
infixl 3 <|>
infixl 4 <*, *>, <$>, <*>
data Parser tok a = Parser { runParser :: [tok] -> Either String ([tok], a) }
instance Monad (Parser tok) where
return = yield
(Parser p) >>= f = Parser $ \ts -> case p ts of
Left e -> Left e
Right (ts', x) -> runParser (f x) ts'
yield :: a -> Parser tok a
yield x = Parser $ \ts -> Right (ts, x)
(<*) :: Parser tok a -> Parser tok b -> Parser tok a
p <* q = const <$> p <*> q
(*>) :: Parser tok a -> Parser tok b -> Parser tok b
p *> q = flip const <$> p <*> q
(<|>) :: Parser tok a -> Parser tok a -> Parser tok a
p <|> q = Parser $ \ts -> case (runParser p) ts of
Left _ -> (runParser q) ts
Right (ts', r) -> Right (ts', r)
eof :: Parser tok a
eof = Parser $ \_ -> Left "Unexpected end-of-file"
unexpected :: Show tok => tok -> Parser tok a
unexpected t = Parser $ \_ -> Left $ "Unexpected token " ++ show t
terminal :: (Eq tok, Show tok) => tok -> Parser tok ()
terminal tok = Parser $ \tokens -> case tokens of
[] -> (runParser eof) []
t:ts | tok == t -> Right (ts, ())
| otherwise -> (runParser (unexpected t)) ts
many :: Parser tok a -> Parser tok [a]
many p = some p <|> yield []
some :: Parser tok a -> Parser tok [a]
some p = (:) <$> p <*> many p
(<$>) :: Monad m => (a -> b) -> m a -> m b
(<$>) f act = act >>= \x -> return (f x)
(<*>) :: Monad m => m (a -> b) -> m a -> m b
a <*> b = a >>= \f -> b >>= \x -> return (f x)
|