on master help sign in
Add takeEndBy parser
commit8ae687f7ce884c4c6ba66b870a1764b2229a992f authorHarendra Kumar <harendra@composewell.com> dateSat 7 May 2022, 12:56 (4 years ago) parent6ed0c93
2 files changed+43−4
core/src/Streamly/Internal/Data/Parser.hs+16−4 core/src/Streamly/Internal/Data/Parser/ParserD.hs+27
core/src/Streamly/Internal/Data/Parser.hs+16−4
@@ -108,7 +108,7 @@ module Streamly.Internal.Data.Parser
108108 , dropWhile
109109
110110 -- ** Separators
111− -- , takeEndBy
111+ , takeEndBy
112112 , takeEndBy_
113113 , takeEndByEsc
114114 -- , takeEndByEsc_
@@ -661,13 +661,25 @@ dropWhile p = takeWhile p FL.drain
661661-------------------------------------------------------------------------------
662662
663663-- | @takeEndBy_ cond parser@ parses a token that ends by a separator chosen by
664−-- the supplied predicate. The separator is dropped.
664+-- the supplied predicate. The separator is also taken with the token.
665665--
666666-- This can be combined with other parsers to implement other interesting
667667-- parsers as follows:
668668--
669−-- >>> takeEndByOrMax cond n p = Parser.takeEndBy_ cond (Parser.fromFold $ Fold.take n p)
670−-- >>> takeEndByBetween cond m n p = Parser.takeEndBy_ cond (Parser.takeBetween m n p)
669+-- >>> takeEndByLE cond n p = Parser.takeEndBy cond (Parser.fromFold $ Fold.take n p)
670+-- >>> takeEndByBetween cond m n p = Parser.takeEndBy cond (Parser.takeBetween m n p)
671+--
672+-- See also "Streamly.Data.Fold.takeEndBy".
673+--
674+-- /Pre-release/
675+--
676+{-# INLINE takeEndBy #-}
677+takeEndBy :: MonadCatch m => (a -> Bool) -> Parser m a b -> Parser m a b
678+takeEndBy cond = D.toParserK . D.takeEndBy cond . D.fromParserK
679+
680+-- | Like 'takeEndBy' but the separator is dropped.
681+--
682+-- See also "Streamly.Data.Fold.takeEndBy_".
671683--
672684-- /Pre-release/
673685--
core/src/Streamly/Internal/Data/Parser/ParserD.hs+27
@@ -72,6 +72,7 @@ module Streamly.Internal.Data.Parser.ParserD
7272 , takeWhile1
7373
7474 -- Separators
75+ , takeEndBy
7576 , takeEndBy_
7677 , takeStartBy
7778
@@ -668,10 +669,36 @@ takeWhile1 predicate (Fold fstep finitial fextract) =
668669-- Separators
669670-------------------------------------------------------------------------------
670671
672+-- | See 'Streamly.Internal.Data.Parser.takeEndBy'.
673+--
674+-- /Pre-release/
675+--
676+{-# INLINE takeEndBy #-}
677+takeEndBy :: MonadCatch m => (a -> Bool) -> Parser m a b -> Parser m a b
678+takeEndBy cond (Parser pstep pinitial pextract) =
679+
680+ Parser step initial pextract
681+
682+ where
683+
684+ initial = pinitial
685+
686+ step s a = do
687+ res <- pstep s a
688+ if not (cond a)
689+ then return res
690+ else do
691+ case res of
692+ Partial n s1 -> Done n <$> pextract s1
693+ Done n b -> return $ Done n b
694+ Continue n s1 -> Done n <$> pextract s1
695+ Error _ -> return res
696+
671697-- | See 'Streamly.Internal.Data.Parser.takeEndBy_'.
672698--
673699-- /Pre-release/
674700--
701+{-# INLINE takeEndBy_ #-}
675702takeEndBy_ :: MonadCatch m =>
676703 (a -> Bool) -> Parser m a b -> Parser m a b
677704takeEndBy_ cond (Parser pstep pinitial pextract) =