@@ -49,6 +49,7 @@ module Data.Attoparsec.Text.Internal
52 , takeWhile
53 , takeWhile
53 , takeWhile1
54 , takeWhile1
54 , takeTill
55 , takeTill
@@ -277,6 +278,26 @@ takeLazyText = L.fromChunks `fmap` takeRest
277data Scan s = Continue s
278data Scan s = Continue s
278 | Finished {-# UNPACK #-} !Int T.Text
279 | Finished {-# UNPACK #-} !Int T.Text
281+scan_ :: (s -> [Text] -> Parser r) -> s -> (s -> Char -> Maybe s) -> Parser r
282+scan_ f s0 p = go [] s0
286+ Just (c,t') -> case p s c of
287+ Just s' -> scanner s' (n+1) t'
288+ Nothing -> Finished n t
289+ Nothing -> Continue s
292+ case scanner s 0 input of
293+ Continue s' -> do put T.empty
296+ then go (input : acc) s'
297+ else f s' (input : acc)
298+ Finished n t -> put t >> f s (T.take n input : acc)
280-- | A stateful scanner. The predicate consumes and transforms a
301-- | A stateful scanner. The predicate consumes and transforms a
281-- state argument, and each transformed state is passed to successive
302-- state argument, and each transformed state is passed to successive
282-- invocations of the predicate on each character of the input until one
303-- invocations of the predicate on each character of the input until one
@@ -289,29 +310,18 @@ data Scan s = Continue s
289-- combinators such as 'many', because such parsers loop until a
310-- combinators such as 'many', because such parsers loop until a
290-- failure occurs. Careless use will thus result in an infinite loop.
311-- failure occurs. Careless use will thus result in an infinite loop.
291scan :: s -> (s -> Char -> Maybe s) -> Parser Text
312scan :: s -> (s -> Char -> Maybe s) -> Parser Text
293− chunks <- go [] s0
313+scan = scan_ $ \_ chunks ->
294 case chunks of
314 case chunks of
295 [x] -> return x
315 [x] -> return x
296 xs -> return . T.concat . reverse $ xs
316 xs -> return . T.concat . reverse $ xs
300− Just (c,t') -> case p s c of
301− Just s' -> scanner s' (n+1) t'
302− Nothing -> Finished n t
303− Nothing -> Continue s
306− case scanner s 0 input of
307− Continue s' -> do put T.empty
310− then go (input : acc) s'
311− else return (input : acc)
312− Finished n t -> put t >> return (T.take n input : acc)
313{-# INLINE scan #-}
317{-# INLINE scan #-}
319+-- | Like 'scan', but generalized to return the final state of the
321+runScanner :: s -> (s -> Char -> Maybe s) -> Parser (Text, s)
322+runScanner = scan_ $ \s xs -> return (T.concat (reverse xs), s)
323+{-# INLINE runScanner #-}
315-- | Consume input as long as the predicate returns 'True', and return
325-- | Consume input as long as the predicate returns 'True', and return
316-- the consumed input.
326-- the consumed input.