on master help sign in
Add takeEndBy parser
8ae687fHarendra Kumar
core/src/Streamly/Internal/Data/Parser.hs+16−4
@@ -108,7 +108,7 @@ module Streamly.Internal.Data.Parser
108 , dropWhile
108 , dropWhile
109
109
110 -- ** Separators
110 -- ** Separators
111− -- , takeEndBy
111+ , takeEndBy
112 , takeEndBy_
112 , takeEndBy_
113 , takeEndByEsc
113 , takeEndByEsc
114 -- , takeEndByEsc_
114 -- , takeEndByEsc_
@@ -661,13 +661,25 @@ dropWhile p = takeWhile p FL.drain
661-------------------------------------------------------------------------------
661-------------------------------------------------------------------------------
662
662
663-- | @takeEndBy_ cond parser@ parses a token that ends by a separator chosen by
663-- | @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.
665--
665--
666-- This can be combined with other parsers to implement other interesting
666-- This can be combined with other parsers to implement other interesting
667-- parsers as follows:
667-- parsers as follows:
668--
668--
669−-- >>> takeEndByOrMax cond n p = Parser.takeEndBy_ cond (Parser.fromFold $ Fold.take 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)
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_".
671--
683--
672-- /Pre-release/
684-- /Pre-release/
673--
685--
core/src/Streamly/Internal/Data/Parser/ParserD.hs+27
@@ -72,6 +72,7 @@ module Streamly.Internal.Data.Parser.ParserD
72 , takeWhile1
72 , takeWhile1
73
73
74 -- Separators
74 -- Separators
75+ , takeEndBy
75 , takeEndBy_
76 , takeEndBy_
76 , takeStartBy
77 , takeStartBy
77
78
@@ -668,10 +669,36 @@ takeWhile1 predicate (Fold fstep finitial fextract) =
668-- Separators
669-- Separators
669-------------------------------------------------------------------------------
670-------------------------------------------------------------------------------
670
671
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+
671-- | See 'Streamly.Internal.Data.Parser.takeEndBy_'.
697-- | See 'Streamly.Internal.Data.Parser.takeEndBy_'.
672--
698--
673-- /Pre-release/
699-- /Pre-release/
674--
700--
701+{-# INLINE takeEndBy_ #-}
675takeEndBy_ :: MonadCatch m =>
702takeEndBy_ :: MonadCatch m =>
676 (a -> Bool) -> Parser m a b -> Parser m a b
703 (a -> Bool) -> Parser m a b -> Parser m a b
677takeEndBy_ cond (Parser pstep pinitial pextract) =
704takeEndBy_ cond (Parser pstep pinitial pextract) =