@@ -15,7 +15,7 @@
1515-----------------------------------------------------------------------------
1616module Data.Attoparsec.Internal
1717 (
18− -- * Parser
18+ -- * Parser types
1919 ParseError
2020 , Parser
2121
@@ -26,43 +26,40 @@ module Data.Attoparsec.Internal
2626
2727 -- * Combinators
2828 , (<?>)
29−
30− -- * Things vaguely like those in @Parsec.Combinator@ (and @Parsec.Prim@)
3129 , try
32− , endOfInput
33− , lookAhead
34− , peek
3530
36− -- * Things like in @Parsec.Char@
31+ -- * Parsing individual bytes
3732 , satisfy
3833 , anyWord8
3934 , word8
4035 , notWord8
36+
37+ -- * Efficient string handling
38+ , match
39+ , notEmpty
40+ , skipWhile
4141 , string
4242 , stringTransform
43+ , takeAll
44+ , takeCount
45+ , takeTill
46+ , takeWhile
47+ , takeWhile1
4348
44− -- * Parser converters.
45− , eitherP
46−
47− -- * Miscellaneous functions.
48− , getInput
49+ -- * State observation functions
50+ , endOfInput
4951 , getConsumed
52+ , getInput
53+ , lookAhead
5054 , setInput
51− , takeWhile
52− , takeWhile1
53− , takeTill
54− , takeAll
55− , takeCount
56− , skipWhile
57− , notEmpty
58− , match
59− , endOfLine
6055
61− -- * Utilities.
56+ -- * Utilities
57+ , endOfLine
6258 , (+:)
6359 ) where
6460
6561import Control.Applicative
62+ (Alternative(..), Applicative(..), (*>))
6663import Control.Monad (MonadPlus(..), ap)
6764import Control.Monad.Fix (MonadFix(..))
6865import qualified Data.ByteString as SB
@@ -75,6 +72,7 @@ import Data.Int (Int64)
7572import Data.Word (Word8)
7673import Prelude hiding (takeWhile)
7774
75+-- ^ A description of a parsing error.
7876type ParseError = String
7977
8078-- State invariants:
@@ -84,6 +82,7 @@ data S = S {-# UNPACK #-} !SB.ByteString
8482 LB.ByteString
8583 {-# UNPACK #-} !Int64
8684
85+-- ^ A parser that produces a result of type @a@.
8786newtype Parser a = Parser {
8887 unParser :: S -> Either (LB.ByteString, [String]) (a, S)
8988 }
@@ -138,8 +137,10 @@ sb +: lb | SB.null sb = lb
138137
139138infix 0 <?>
140139
141−-- | Name the parser.
142−(<?>) :: Parser a -> String -> Parser a
140+-- | Name the parser, in case failure occurs.
141+(<?>) :: Parser a
142+ -> String -- ^ the name to use if parsing fails
143+ -> Parser a
143144p <?> msg =
144145 Parser $ \s@(S sb lb _) ->
145146 case unParser p s of
@@ -165,7 +166,7 @@ setInput bs = Parser $ \(S _ _ n) -> Right ((), mkState bs n)
165166getConsumed :: Parser Int64
166167getConsumed = Parser $ \s@(S _ _ n) -> Right (n, s)
167168
168−-- | Character parser.
169+-- | Match a single byte based on the given predicate.
169170satisfy :: (Word8 -> Bool) -> Parser Word8
170171satisfy p =
171172 Parser $ \s@(S sb lb n) ->
@@ -175,7 +176,7 @@ satisfy p =
175176 Nothing -> unParser (nextChunk >> satisfy p) s
176177{-# INLINE satisfy #-}
177178
178−-- | Satisfy a literal string.
179+-- | Match a literal string exactly.
179180string :: LB.ByteString -> Parser LB.ByteString
180181string s = Parser $ \(S sb lb n) ->
181182 let bs = sb +: lb
@@ -186,6 +187,8 @@ string s = Parser $ \(S sb lb n) ->
186187 else Left (bs, [])
187188{-# INLINE string #-}
188189
190+-- | Match the end of a line. This may be any of a newline character,
191+-- a carriage return character, or a carriage return followed by a newline.
189192endOfLine :: Parser ()
190193endOfLine = Parser $ \(S sb lb n) ->
191194 let bs = sb +: lb
@@ -200,8 +203,9 @@ endOfLine = Parser $ \(S sb lb n) ->
200203 else Right ((), mkState (LB.tail bs) (n + 1))
201204 _ -> Left (bs, ["EOL"])
202205
203−-- | Satisfy a literal string, after applying a transformation to both
204−-- it and the matching text.
206+-- | Match a literal string, after applying a transformation to both
207+-- it and the matching text. Useful for e.g. case insensitive string
208+-- comparison.
205209stringTransform :: (LB.ByteString -> LB.ByteString) -> LB.ByteString
206210 -> Parser LB.ByteString
207211stringTransform f s = Parser $ \(S sb lb n) ->
@@ -214,23 +218,27 @@ stringTransform f s = Parser $ \(S sb lb n) ->
214218 where fs = f s
215219{-# INLINE stringTransform #-}
216220
221+-- | Attempt a parse, but do not consume any input if the parse fails.
217222try :: Parser a -> Parser a
218223try p = Parser $ \s@(S sb lb _) ->
219224 case unParser p s of
220225 Left (_, msgs) -> Left (sb +: lb, msgs)
221226 ok -> ok
222227
223−-- | Detect 'end of file'.
228+-- | Succeed if we have reached the end of the input string.
224229endOfInput :: Parser ()
225230endOfInput = Parser $ \s@(S sb lb _) -> if SB.null sb && LB.null lb
226231 then Right ((), s)
227232 else Left (sb +: lb, ["EOF"])
228233
234+-- | Return all of the remaining input as a single string.
229235takeAll :: Parser LB.ByteString
230236takeAll = Parser $ \(S sb lb n) ->
231237 let bs = sb +: lb
232238 in Right (bs, mkState LB.empty (n + LB.length bs))
233239
240+-- | Return exactly the given number of bytes. If not enough are
241+-- available, fail.
234242takeCount :: Int -> Parser LB.ByteString
235243takeCount k =
236244 Parser $ \(S sb lb n) ->
@@ -241,7 +249,7 @@ takeCount k =
241249 then Right (h, mkState t (n + k'))
242250 else Left (bs, [show k ++ " bytes"])
243251
244−-- | Consume characters while the predicate is true.
252+-- | Consume bytes while the predicate succeeds.
245253takeWhile :: (Word8 -> Bool) -> Parser LB.ByteString
246254takeWhile p =
247255 Parser $ \(S sb lb n) ->
@@ -249,14 +257,17 @@ takeWhile p =
249257 in Right (h, mkState t (n + LB.length h))
250258{-# INLINE takeWhile #-}
251259
260+-- | Consume bytes while the predicate fails. If the predicate never
261+-- succeeds, the entire input string is returned.
252262takeTill :: (Word8 -> Bool) -> Parser LB.ByteString
253263takeTill p =
254264 Parser $ \(S sb lb n) ->
255− case LB.break p (sb +: lb) of
256− (h,t) | LB.null t -> Left (h, [])
257− | otherwise -> Right (h, mkState t (n + LB.length h))
265+ let (h,t) = LB.break p (sb +: lb)
266+ in Right (h, mkState t (n + LB.length h))
258267{-# INLINE takeTill #-}
259268
269+-- | Consume bytes while the predicate is true. Fails if the
270+-- predicate fails on the first byte.
260271takeWhile1 :: (Word8 -> Bool) -> Parser LB.ByteString
261272takeWhile1 p =
262273 Parser $ \(S sb lb n) ->
@@ -265,7 +276,7 @@ takeWhile1 p =
265276 | otherwise -> Right (h, mkState t (n + LB.length h))
266277{-# INLINE takeWhile1 #-}
267278
268−-- | Test that a parser returned a non-null ByteString.
279+-- | Test that a parser returned a non-null 'LB.ByteString'.
269280notEmpty :: Parser LB.ByteString -> Parser LB.ByteString
270281notEmpty p = Parser $ \s ->
271282 case unParser p s of
@@ -275,8 +286,8 @@ notEmpty p = Parser $ \s ->
275286 else o
276287 x -> x
277288
278−-- | Parse some input with the given parser and return that input
279−-- without copying it.
289+-- | Parse some input with the given parser, and return the input it
290+-- consumed as a string.
280291match :: Parser a -> Parser LB.ByteString
281292match p = do bs <- getInput
282293 start <- getConsumed
@@ -284,23 +295,18 @@ match p = do bs <- getInput
284295 end <- getConsumed
285296 return (LB.take (end - start) bs)
286297
287−eitherP :: Parser a -> Parser b -> Parser (Either a b)
288−eitherP a b = (Left <$> a) <|> (Right <$> b)
289−{-# INLINE eitherP #-}
290−
291−peek :: Parser a -> Parser (Maybe a)
292−peek p = Parser $ \s ->
293− case unParser p s of
294− Right (m, _) -> Right (Just m, s)
295− _ -> Right (Nothing, s)
296−
298+-- | Apply a parser without consuming any input.
297299lookAhead :: Parser a -> Parser a
298300lookAhead p = Parser $ \s ->
299301 case unParser p s of
300302 Right (m, _) -> Right (m, s)
301− Left (e, bs) -> Left (e, bs)
303+ err -> err
302304
303−parseAt :: Parser a -> LB.ByteString -> Int64
305+-- | Run a parser. The 'Int64' value is used as a base to count the
306+-- number of bytes consumed.
307+parseAt :: Parser a -- ^ parser to run
308+ -> LB.ByteString -- ^ input to parse
309+ -> Int64 -- ^ offset to count input from
304310 -> (LB.ByteString, Either ParseError (a, Int64))
305311parseAt p bs n =
306312 case unParser p (mkState bs n) of
@@ -313,12 +319,14 @@ parseAt p bs n =
313319 showError msgs = "Parser error, expected one of:\n" ++ unlines msgs
314320
315321-- | Run a parser.
316−parse :: Parser a -> LB.ByteString
322+parse :: Parser a -- ^ parser to run
323+ -> LB.ByteString -- ^ input to parse
317324 -> (LB.ByteString, Either ParseError a)
318325parse p bs = case parseAt p bs 0 of
319326 (bs', Right (a, _)) -> (bs', Right a)
320327 (bs', Left err) -> (bs', Left err)
321328
329+-- | Try out a parser, and print its result.
322330parseTest :: (Show a) => Parser a -> LB.ByteString -> IO ()
323331parseTest p s =
324332 case parse p s of