@@ -140,11 +140,13 @@ module Streamly.Internal.Data.Parser
140 -- ** Sequential Repetition
140 -- ** Sequential Repetition
142 , countBetween
142 , countBetween
143− -- , countBetweenTill
147 , manyTill
148 , manyTill
149 -- ** Special cases
151 -- ** Special cases
150 -- | TODO: traditional implmentations of these may be of limited use. For
152 -- | TODO: traditional implmentations of these may be of limited use. For
@@ -177,10 +179,7 @@ module Streamly.Internal.Data.Parser
178 -- 1. Round robin
180 -- 1. Round robin
179 -- 2. Priority based
181 -- 2. Priority based
181− -- ** Interleaved repetition
182− -- | repeat one parser and when it fails run an error recovery parser
183− -- e.g. to find a key frame in the stream after an error
185 -- ** Collection of Alternatives
184 -- ** Collection of Alternatives
186 -- | Unimplemented
185 -- | Unimplemented
@@ -194,13 +193,9 @@ module Streamly.Internal.Data.Parser
194 , choice -- first successful in position
193 , choice -- first successful in position
196 -- ** Repeated Alternatives
195 -- ** Repeated Alternatives
197− -- |
196+ , retryMaxTotal
198− --
197+ , retryMaxSuccessive
200− -- , retryMax -- try N times
201− -- , retryUntil -- try until successful
202− -- , retryUntilN -- try until successful n times
@@ -898,6 +893,8 @@ deintercalate = undefined
898-- | @sequence f t@ collects sequential parses of parsers in the container @t@
893-- | @sequence f t@ collects sequential parses of parsers in the container @t@
899-- using the fold @f@. Fails if the input ends or any of the parsers fail.
894-- using the fold @f@. Fails if the input ends or any of the parsers fail.
896+-- This is same as 'Data.Traversable.sequence' but more efficient.
901-- /Unimplemented/
898-- /Unimplemented/
903{-# INLINE sequence #-}
900{-# INLINE sequence #-}
@@ -927,6 +924,10 @@ concatMap f p = D.toParserK $ D.concatMap (D.fromParserK . f) (D.fromParserK p)
927-- | @choice parsers@ applies the @parsers@ in order and returns the first
924-- | @choice parsers@ applies the @parsers@ in order and returns the first
928-- successful parse.
925-- successful parse.
927+-- This is same as 'asum' but more efficient.
930{-# INLINE choice #-}
931{-# INLINE choice #-}
932 -- Foldable t =>
933 -- Foldable t =>
@@ -942,6 +943,16 @@ choice _ps = undefined
942-- downgraded to a Fold. Or we can make the return type a Fold instead and
943-- downgraded to a Fold. Or we can make the return type a Fold instead and
943-- upgrade that to a parser when needed.
944-- upgrade that to a parser when needed.
946+-- | Like 'many' but uses a 'Parser' instead of a 'Fold' to collect the
947+-- results. Parsing stops or fails if the collecting parser stops or fails.
952+manyP :: -- MonadCatch m =>
953+ Parser m b c -> Parser m a b -> Parser m a c
954+manyP _f _p = undefined -- D.toParserK $ D.manyP f (D.fromParserK p)
945-- | Collect zero or more parses. Apply the parser repeatedly on the input
956-- | Collect zero or more parses. Apply the parser repeatedly on the input
946-- stream, stop when the parser fails, accumulate zero or more parse results
957-- stream, stop when the parser fails, accumulate zero or more parse results
947-- using the supplied 'Fold'. This parser never fails, in case the first
958-- using the supplied 'Fold'. This parser never fails, in case the first
@@ -968,7 +979,7 @@ many f p = D.toParserK $ D.many f (D.fromParserK p)
968{-# INLINE some #-}
979{-# INLINE some #-}
969some :: MonadCatch m => Fold m b c -> Parser m a b -> Parser m a c
980some :: MonadCatch m => Fold m b c -> Parser m a b -> Parser m a c
970some f p = D.toParserK $ D.some f (D.fromParserK p)
981some f p = D.toParserK $ D.some f (D.fromParserK p)
971−-- some f p = many (takeGE 1 f) p
982+-- some f p = manyP (takeGE 1 f) p
972-- many = countBetween 1 maxBound
983-- many = countBetween 1 maxBound
974-- | @countBetween m n f p@ collects between @m@ and @n@ sequential parses of
985-- | @countBetween m n f p@ collects between @m@ and @n@ sequential parses of
@@ -982,7 +993,7 @@ countBetween ::
982 -- MonadCatch m =>
993 -- MonadCatch m =>
983 Int -> Int -> Fold m b c -> Parser m a b -> Parser m a c
994 Int -> Int -> Fold m b c -> Parser m a b -> Parser m a c
984countBetween _m _n _f = undefined
995countBetween _m _n _f = undefined
985−-- countBetween m n f p = many (takeBetween m n f) p
996+-- countBetween m n f p = manyP (takeBetween m n f) p
987-- | @count n f p@ collects exactly @n@ sequential parses of parser @p@ using
998-- | @count n f p@ collects exactly @n@ sequential parses of parser @p@ using
988-- the fold @f@. Fails if the input ends or the parser fails before @n@
999-- the fold @f@. Fails if the input ends or the parser fails before @n@
@@ -995,7 +1006,24 @@ count ::
995 -- MonadCatch m =>
1006 -- MonadCatch m =>
996 Int -> Fold m b c -> Parser m a b -> Parser m a c
1007 Int -> Fold m b c -> Parser m a b -> Parser m a c
997count n = countBetween n n
1008count n = countBetween n n
998−-- count n f p = many (takeEQ n f) p
1009+-- count n f p = manyP (takeEQ n f) p
1011+-- | Like 'manyTill' but uses a 'Parser' to collect the results instead of a
1012+-- 'Fold'. Parsing stops or fails if the collecting parser stops or fails.
1014+-- We can implemnent parsers like the following using 'manyTillP':
1017+-- countBetweenTill m n f p = manyTillP (takeBetween m n f) p
1022+{-# INLINE manyTillP #-}
1023+manyTillP :: -- MonadCatch m =>
1024+ Parser m b c -> Parser m a b -> Parser m a x -> Parser m a c
1025+manyTillP _f _p1 _p2 = undefined
1026+ -- D.toParserK $ D.manyTillP f (D.fromParserK p1) (D.fromParserK p2)
1000-- | @manyTill f collect test@ tries the parser @test@ on the input, if @test@
1028-- | @manyTill f collect test@ tries the parser @test@ on the input, if @test@
1001-- fails it backtracks and tries @collect@, after @collect@ succeeds @test@ is
1029-- fails it backtracks and tries @collect@, after @collect@ succeeds @test@ is
@@ -1010,3 +1038,68 @@ manyTill :: MonadCatch m
1010 => Fold m b c -> Parser m a b -> Parser m a x -> Parser m a c
1038 => Fold m b c -> Parser m a b -> Parser m a x -> Parser m a c
1011manyTill f p1 p2 =
1039manyTill f p1 p2 =
1012 D.toParserK $ D.manyTill f (D.fromParserK p1) (D.fromParserK p2)
1040 D.toParserK $ D.manyTill f (D.fromParserK p1) (D.fromParserK p2)
1042+-- | @manyThen f collect recover@ repeats the parser @collect@ on the input and
1043+-- collects the output in the supplied fold. If the the parser @collect@ fails,
1044+-- parser @recover@ is run until it stops and then we start repeating the
1045+-- parser @collect@ again. The parser fails if the recovery parser fails.
1047+-- For example, this can be used to find a key frame in a video stream after an
1052+{-# INLINE manyThen #-}
1053+manyThen :: -- (Foldable t, MonadCatch m) =>
1054+ Fold m b c -> Parser m a b -> Parser m a x -> Parser m a c
1055+manyThen _f _parser _recover = undefined
1057+-------------------------------------------------------------------------------
1058+-- Interleaving a collection of parsers
1059+-------------------------------------------------------------------------------
1061+-- | Apply a collection of parsers to an input stream in a round robin fashion.
1062+-- Each parser is applied until it stops and then we repeat starting with the
1063+-- the first parser again.
1067+{-# INLINE roundRobin #-}
1068+roundRobin :: -- (Foldable t, MonadCatch m) =>
1069+ Fold m b c -> t (Parser m a b) -> Parser m a c
1070+roundRobin _f _ps = undefined
1072+-------------------------------------------------------------------------------
1073+-- Repeated Alternatives
1074+-------------------------------------------------------------------------------
1076+-- | Keep trying a parser up to a maximum of @n@ failures. When the parser
1077+-- fails the input consumed till now is dropped and the new instance is tried
1078+-- on the fresh input.
1082+{-# INLINE retryMaxTotal #-}
1083+retryMaxTotal :: -- (MonadCatch m) =>
1084+ Int -> Fold m b c -> Parser m a b -> Parser m a c
1085+retryMaxTotal _n _f _p = undefined
1087+-- | Like 'retryMaxTotal' but aborts after @n@ successive failures.
1091+{-# INLINE retryMaxSuccessive #-}
1092+retryMaxSuccessive :: -- (MonadCatch m) =>
1093+ Int -> Fold m b c -> Parser m a b -> Parser m a c
1094+retryMaxSuccessive _n _f _p = undefined
1096+-- | Keep trying a parser until it succeeds. When the parser fails the input
1097+-- consumed till now is dropped and the new instance is tried on the fresh
1102+{-# INLINE retry #-}
1103+retry :: -- (MonadCatch m) =>
1104+ Parser m a b -> Parser m a b
1105+retry _p = undefined