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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
module DetParser where
type Parser token a = [token] -> Either ParseError ([token], a)
type ParseError = String
(<*) :: Parser token a -> Parser token b -> Parser token a
a <* b = const <$> a <*> b
(*>) :: Parser token a -> Parser token b -> Parser token b
a *> b = const id <$> a <*> b
(<*>) :: Parser token (a -> b) -> Parser token a -> Parser token b
a <*> b = \ts -> case a ts of
Left e -> Left e
Right (ts', f) -> case b ts' of
Left e -> Left e
Right (ts2, x) -> Right (ts2, f x)
(<|>) :: Parser token a -> Parser token a -> Parser token a
a <|> b = \ts -> case a ts of
Right (ts', x) -> Right (ts', x)
Left e -> case b ts of
Left e' -> Left $ "parse error: " ++ e' ++ " | " ++ e
Right (ts2, y) -> Right (ts2, y)
(<$>) :: (a -> b) -> Parser token a -> Parser token b
f <$> p = yield f <*> p
liftP2 :: (a -> b -> r) -> Parser token a -> Parser token b -> Parser token r
liftP2 f p1 p2 = \ts -> case p1 ts of
Left e -> Left e
Right (ts', x) -> case p2 ts' of
Left e -> Left e
Right (ts2, y) -> Right (ts2, f x y)
yield :: a -> Parser token a
yield x ts = Right (ts, x)
terminal :: token -> Parser token ()
terminal _ [] = eof []
terminal x (t:ts) = case x == t of
True -> Right (ts, ())
False -> unexpected t ts
eof :: Parser token a
eof _ = Left "unexpected end-of-file"
unexpected :: token -> Parser token a
unexpected t _ = Left $ "unexpected token " ++ show t
star :: Parser token a -> Parser token [a]
star p = (\ts -> case p ts of
Left e -> Left e
Right (ts', x) -> (x:) <$> star p $ ts')
<|> yield []
some :: Parser token a -> Parser token [a]
some p = \ts -> case p ts of
Left e -> Left e
Right (ts', x) -> (x:) <$> star p $ ts'
|