@@ -3,6 +3,8 @@ module Parsing where
3
3
import Prelude
4
4
import Either
5
5
import String
6
+ import Arrays
7
+ import Maybe
6
8
7
9
data ParseError = ParseError
8
10
{ message :: String
@@ -15,41 +17,153 @@ parseError message = ParseError
15
17
16
18
data ParseResult s a = ParseResult
17
19
{ leftover :: s
18
- , result :: a
20
+ , consumed :: Boolean
21
+ , result :: Either ParseError a
19
22
}
20
23
21
- parseResult :: forall s a . s -> a -> ParseResult s a
22
- parseResult leftover result = ParseResult
24
+ parseResult :: forall s a . s -> Boolean -> Either ParseError a -> ParseResult s a
25
+ parseResult leftover consumed result = ParseResult
23
26
{ leftover: leftover
27
+ , consumed: consumed
24
28
, result: result
25
29
}
26
30
27
- data Parser s a = Parser (s -> Either ParseError (ParseResult s a ))
31
+ successResult :: forall s a . s -> Boolean -> a -> ParseResult s a
32
+ successResult leftover consumed result = parseResult leftover consumed (Right result)
28
33
29
- runParser :: forall s a . Parser s a -> s -> Either ParseError ( ParseResult s a )
30
- runParser ( Parser p) s = p s
34
+ failureResult :: forall s a . s -> Boolean -> ParseError -> ParseResult s a
35
+ failureResult leftover consumed err = parseResult leftover consumed ( Left err)
31
36
32
- fail :: String -> forall s a . Parser s a
33
- fail message = Parser $ \s -> Left (parseError message )
37
+ instance Prelude.Functor ( ParseResult s ) where
38
+ (<$>) f ( ParseResult o) = parseResult o.leftover o.consumed (f <$> o.result )
34
39
35
- string :: String -> Parser String String
36
- string s = Parser $ \s' -> case indexOfS s' s of
37
- 0 -> Right $ parseResult (substring (lengthS s) (lengthS s') s') s
38
- _ -> Left $ parseError $ " Expected \" " ++ s ++ " \" "
40
+ data Parser s a = Parser (s -> ParseResult s a )
39
41
40
- char :: Parser String String
41
- char = Parser $ \s -> case s of
42
- " " -> Left $ parseError $ " Unexpected EOF"
43
- _ -> Right $ parseResult (substring 1 (lengthS s) s) (substr 0 1 s)
42
+ runParser :: forall s a . Parser s a -> s -> ParseResult s a
43
+ runParser (Parser p) s = p s
44
44
45
45
instance Prelude.Monad (Parser s ) where
46
- return a = Parser $ \s -> Right (parseResult s a)
47
- (>>=) ( Parser p) f = Parser $ \s -> case p s of
48
- Left err -> Left err
49
- Right ( ParseResult { leftover = s, result = a }) -> runParser (f a) s
46
+ return a = Parser $ \s -> successResult s false a
47
+ (>>=) p f = Parser $ \s -> case runParser p s of
48
+ ParseResult ({ leftover = s', consumed = consumed, result = Left err }) -> failureResult s' consumed err
49
+ ParseResult ( { leftover = s', consumed = consumed, result = Right a }) -> runParser (f a) s' -- TODO
50
50
51
51
instance Prelude.Alternative (Parser s ) where
52
52
empty = fail " No alternative"
53
53
(<|>) p1 p2 = Parser $ \s -> case runParser p1 s of
54
- Left _ -> runParser p2 s
55
- Right res -> Right res
54
+ ParseResult ({ leftover = s', consumed = false , result = Left _ }) -> runParser p2 s
55
+ res -> res
56
+
57
+ -- Polymorphic Parser Combinators
58
+
59
+ fail :: forall s a . String -> Parser s a
60
+ fail message = Parser $ \s -> failureResult s false (parseError message)
61
+
62
+ (<?>) :: forall s a . Parser s a -> String -> Parser s a
63
+ (<?>) p msg = p <|> fail msg
64
+
65
+ many :: forall s a . Parser s a -> Parser s [a ]
66
+ many p = many1 p <|> return []
67
+
68
+ many1 :: forall s a . Parser s a -> Parser s [a ]
69
+ many1 p = do a <- p
70
+ as <- many p
71
+ return (a : as)
72
+
73
+ between :: forall s a open close . Parser s open -> Parser s close -> ({ } -> Parser s a ) -> Parser s a
74
+ between open close p = do
75
+ open
76
+ a <- p {}
77
+ close
78
+ return a
79
+
80
+ option :: forall s a . a -> Parser s a -> Parser s a
81
+ option a p = p <|> return a
82
+
83
+ optional :: forall s a . Parser s a -> Parser s { }
84
+ optional p = (do p
85
+ return {}) <|> return {}
86
+
87
+ optionMaybe :: forall s a . Parser s a -> Parser s (Maybe a )
88
+ optionMaybe p = option Nothing (Just <$> p)
89
+
90
+ try :: forall s a . Parser s a -> Parser s a
91
+ try p = Parser $ \s -> case runParser p s of
92
+ ParseResult ({ consumed = true , result = Left err }) -> failureResult s false err
93
+ res -> res
94
+
95
+ sepBy :: forall s a sep . Parser s a -> Parser s sep -> Parser s [a ]
96
+ sepBy p sep = sepBy1 p sep <|> return []
97
+
98
+ sepBy1 :: forall s a sep . Parser s a -> Parser s sep -> Parser s [a ]
99
+ sepBy1 p sep = do
100
+ a <- p
101
+ as <- many $ do
102
+ sep
103
+ p
104
+ return (a : as)
105
+
106
+ sepEndBy :: forall s a sep . Parser s a -> Parser s sep -> Parser s [a ]
107
+ sepEndBy p sep = sepEndBy1 p sep <|> return []
108
+
109
+ sepEndBy1 :: forall s a sep . Parser s a -> Parser s sep -> Parser s [a ]
110
+ sepEndBy1 p sep = do
111
+ a <- p
112
+ (do sep
113
+ as <- sepEndBy p sep
114
+ return (a : as)) <|> return [a]
115
+
116
+ endBy1 :: forall s a sep . Parser s a -> Parser s sep -> Parser s [a ]
117
+ endBy1 p sep = many1 $ do
118
+ a <- p
119
+ sep
120
+ return a
121
+
122
+ endBy :: forall s a sep . Parser s a -> Parser s sep -> Parser s [a ]
123
+ endBy p sep = many $ do
124
+ a <- p
125
+ sep
126
+ return a
127
+
128
+ chainr :: forall s a . Parser s a -> Parser s (a -> a -> a ) -> a -> Parser s a
129
+ chainr p f a = chainr1 p f <|> return a
130
+
131
+ chainl :: forall s a . Parser s a -> Parser s (a -> a -> a ) -> a -> Parser s a
132
+ chainl p f a = chainl1 p f <|> return a
133
+
134
+ chainl1 :: forall s a . Parser s a -> Parser s (a -> a -> a ) -> Parser s a
135
+ chainl1 p f = do
136
+ a <- p
137
+ chainl1' p f a
138
+
139
+ chainl1' :: forall s a . Parser s a -> Parser s (a -> a -> a ) -> a -> Parser s a
140
+ chainl1' p f a = (do f' <- f
141
+ a' <- p
142
+ chainl1' p f (f' a a')) <|> return a
143
+
144
+ chainr1 :: forall s a . Parser s a -> Parser s (a -> a -> a ) -> Parser s a
145
+ chainr1 p f = do
146
+ a <- p
147
+ chainr1' p f a
148
+
149
+ chainr1' :: forall s a . Parser s a -> Parser s (a -> a -> a ) -> a -> Parser s a
150
+ chainr1' p f a = (do f' <- f
151
+ a' <- chainr1 p f
152
+ return $ f' a a') <|> return a
153
+
154
+ -- String Parsers
155
+
156
+ eof :: Parser String { }
157
+ eof = Parser $ \s -> case s of
158
+ " " -> successResult s false {}
159
+ _ -> failureResult s false $ parseError " Expected EOF"
160
+
161
+ string :: String -> Parser String String
162
+ string s = Parser $ \s' -> case indexOfS s' s of
163
+ 0 -> successResult (substring (lengthS s) (lengthS s') s') true s
164
+ _ -> failureResult s' false $ parseError $ " Expected \" " ++ s ++ " \" "
165
+
166
+ char :: Parser String String
167
+ char = Parser $ \s -> case s of
168
+ " " -> failureResult s false $ parseError " Unexpected EOF"
169
+ _ -> successResult (substring 1 (lengthS s) s) true (substr 0 1 s)
0 commit comments