on master help sign in
Add skeleton for some unimplemented parsers
9b511beHarendra Kumar
src/Streamly/Internal/Data/Parser.hs+117−35
@@ -72,56 +72,29 @@ module Streamly.Internal.Data.Parser
72 --
72 --
73 -- | Parsers chained in series, if one parser terminates the composition
73 -- | Parsers chained in series, if one parser terminates the composition
74 -- terminates.
74 -- terminates.
75− --
76− -- TODO: Currently we are using folds to collect the output of the parsers
77− -- but we can use Parsers instead of folds to make the composition more
78− -- powerful. For example, we can do:
79− --
80− -- @
81− -- sliceSepByMax cond n p = sliceBy cond (take n p)
82− -- sliceSepByBetween cond m n p = sliceBy cond (takeBetween m n p)
83− -- takeWhileBetween cond m n p = takeWhile cond (takeBetween m n p)
84− -- @
85− --
86− -- TODO: Like toList fold we can have toNonEmpty Parser to fold to a
87− -- nonempty list. If we cannot collect even one element the parser will
88− -- fail. toNonEmpty can be used in takeWhile to implement takeWhile1.
89
75
90 -- | Grab a sequence of input elements without inspecting them
76 -- | Grab a sequence of input elements without inspecting them
91− , take
77+ , takeBetween
78+ , take -- takeBetween 0 n
92 -- $take
79 -- $take
93− -- | Unimplemented
94− --
95− -- @
96− -- , takeBetween
97− -- , takeLE -- take -- takeBetween 0 n
98− -- , takeLE1 -- take1 -- takeBetween 1 n
99− -- @
100 , takeEQ -- takeBetween n n
80 , takeEQ -- takeBetween n n
101 , takeGE -- takeBetween n maxBound
81 , takeGE -- takeBetween n maxBound
102
82
103 -- Grab a sequence of input elements by inspecting them
83 -- Grab a sequence of input elements by inspecting them
104 , lookAhead
84 , lookAhead
85+ , takeWhileP
105 , takeWhile
86 , takeWhile
106 -- $takeWhile
87 -- $takeWhile
107 , takeWhile1
88 , takeWhile1
89+
90+ , sliceSepByP
108 , sliceSepBy
91 , sliceSepBy
109 , sliceSepByMax
92 , sliceSepByMax
110− -- | Unimplemented
111− --
112− -- @
113− -- , sliceSepByBetween
114− -- @
115 , sliceEndWith
93 , sliceEndWith
116 , sliceBeginWith
94 , sliceBeginWith
117− -- | Unimplemented
118− --
119− -- @
120− -- , sliceSepWith
95+ , sliceSepWith
121− --
96+ , escapedSliceSepBy
122− -- , frameSepBy -- parse frames escaped by an escape char/sequence
97+ , escapedFrameBy
123− -- , frameEndWith
124− -- @
125 , wordBy
98 , wordBy
126 , groupBy
99 , groupBy
127 , eqBy
100 , eqBy
@@ -365,6 +338,30 @@ satisfy = D.toParserK . D.satisfy
365-------------------------------------------------------------------------------
338-------------------------------------------------------------------------------
366-- Taking elements
339-- Taking elements
367-------------------------------------------------------------------------------
340-------------------------------------------------------------------------------
341+
342+-- | @takeBetween m n@ takes a minimum of @m@ and a maximum of @n@ input
343+-- elements and folds them using the supplied fold.
344+--
345+-- Stops after @n@ elements.
346+-- Fails if the stream ends before @m@ elements could be taken.
347+--
348+-- @takeBetween@ is the most general take operation, other take operations can
349+-- be defined in terms of takeBetween. For example:
350+--
351+-- @
352+-- take = takeBetween 0 n -- equivalent of takeLE
353+-- take1 = takeBetween 1 n -- equivalent of takeLE1
354+-- takeEQ = takeBetween n n
355+-- takeGE = takeBetween n maxBound
356+-- @
357+--
358+-- /Unimplemented/
359+--
360+{-# INLINE takeBetween #-}
361+takeBetween :: -- MonadCatch m =>
362+ Int -> Int -> Fold m a b -> Parser m a b
363+takeBetween _m _n = undefined -- D.toParserK . D.takeBetween m n
364+
368--
365--
369-- $take
366-- $take
370-- Note: this is called takeP in some parser libraries.
367-- Note: this is called takeP in some parser libraries.
@@ -428,6 +425,27 @@ takeGE n = D.toParserK . D.takeGE n
428-- $takeWhile
425-- $takeWhile
429-- Note: This is called @takeWhileP@ and @munch@ in some parser libraries.
426-- Note: This is called @takeWhileP@ and @munch@ in some parser libraries.
430
427
428+-- | Like 'takeWhile' but uses a 'Parser' instead of a 'Fold' to collect the
429+-- input. The combinator stops when the condition fails or if the collecting
430+-- parser stops.
431+--
432+-- This is a generalized version of takeWhile, for example 'takeWhile1' can be
433+-- implemented in terms of this:
434+--
435+-- @
436+-- takeWhile1 cond p = takeWhile cond (takeBetween 1 maxBound p)
437+-- @
438+--
439+-- Stops: when the condition fails or the collecting parser stops.
440+-- Fails: when the collecting parser fails.
441+--
442+-- /Unimplemented/
443+--
444+{-# INLINE takeWhileP #-}
445+takeWhileP :: -- MonadCatch m =>
446+ (a -> Bool) -> Parser m a b -> Parser m a b
447+takeWhileP _cond = undefined -- D.toParserK . D.takeWhileP cond
448+
431-- | Collect stream elements until an element fails the predicate. The element
449-- | Collect stream elements until an element fails the predicate. The element
432-- on which the predicate fails is returned back to the input stream.
450-- on which the predicate fails is returned back to the input stream.
433--
451--
@@ -457,6 +475,25 @@ takeWhile cond = D.toParserK . D.takeWhile cond
457takeWhile1 :: MonadCatch m => (a -> Bool) -> Fold m a b -> Parser m a b
475takeWhile1 :: MonadCatch m => (a -> Bool) -> Fold m a b -> Parser m a b
458takeWhile1 cond = D.toParserK . D.takeWhile1 cond
476takeWhile1 cond = D.toParserK . D.takeWhile1 cond
459
477
478+-- | Like 'sliceSepBy' but uses a 'Parser' instead of a 'Fold' to collect the
479+-- input. @sliceSepByP cond parser@ parses a slice of the input using @parser@
480+-- until @cond@ succeeds or the parser stops.
481+--
482+-- This is a generalized slicing parser which can be used to implement other
483+-- parsers e.g.:
484+--
485+-- @
486+-- sliceSepByMax cond n p = sliceBy cond (take n p)
487+-- sliceSepByBetween cond m n p = sliceBy cond (takeBetween m n p)
488+-- @
489+--
490+-- /Unimplemented/
491+--
492+{-# INLINABLE sliceSepByP #-}
493+sliceSepByP :: -- MonadCatch m =>
494+ (a -> Bool) -> Parser m a b -> Parser m a b
495+sliceSepByP _cond = undefined -- D.toParserK . D.sliceSepByP cond
496+
460-- Note: Keep this consistent with S.splitOn. In fact we should eliminate
497-- Note: Keep this consistent with S.splitOn. In fact we should eliminate
461-- S.splitOn in favor of the parser.
498-- S.splitOn in favor of the parser.
462--
499--
@@ -506,6 +543,15 @@ takeWhile1 cond = D.toParserK . D.takeWhile1 cond
506sliceSepBy :: MonadCatch m => (a -> Bool) -> Fold m a b -> Parser m a b
543sliceSepBy :: MonadCatch m => (a -> Bool) -> Fold m a b -> Parser m a b
507sliceSepBy cond = D.toParserK . D.sliceSepBy cond
544sliceSepBy cond = D.toParserK . D.sliceSepBy cond
508
545
546+-- | Like 'sliceSepBy' but does not drop the separator element, instead
547+-- separator is emitted as a separate element in the output.
548+--
549+-- /Unimplemented/
550+{-# INLINABLE sliceSepWith #-}
551+sliceSepWith :: -- MonadCatch m =>
552+ (a -> Bool) -> Fold m a b -> Parser m a b
553+sliceSepWith _cond = undefined -- D.toParserK . D.sliceSepBy cond
554+
509-- | Collect stream elements until an element succeeds the predicate. Also take
555-- | Collect stream elements until an element succeeds the predicate. Also take
510-- the element on which the predicate succeeded. The succeeding element is
556-- the element on which the predicate succeeded. The succeeding element is
511-- treated as a suffix separator which is kept in the output segement.
557-- treated as a suffix separator which is kept in the output segement.
@@ -580,6 +626,42 @@ sliceSepByMax :: MonadCatch m
580 => (a -> Bool) -> Int -> Fold m a b -> Parser m a b
626 => (a -> Bool) -> Int -> Fold m a b -> Parser m a b
581sliceSepByMax cond cnt = D.toParserK . D.sliceSepByMax cond cnt
627sliceSepByMax cond cnt = D.toParserK . D.sliceSepByMax cond cnt
582
628
629+-- | Like 'sliceSepBy' but the separator elements can be escaped using an
630+-- escape char determined by the second predicate.
631+--
632+-- /Unimplemented/
633+{-# INLINABLE escapedSliceSepBy #-}
634+escapedSliceSepBy :: -- MonadCatch m =>
635+ (a -> Bool) -> (a -> Bool) -> Fold m a b -> Parser m a b
636+escapedSliceSepBy _cond _esc = undefined
637+ -- D.toParserK . D.escapedSliceSepBy cond esc
638+
639+-- | @escapedFrameBy begin end escape@ parses a string framed using @begin@ and
640+-- @end@ as the frame begin and end marker elements and @escape@ as an escaping
641+-- element to escape the occurrence of the framing elements within the frame.
642+-- Nested frames are allowed, but nesting is removed when parsing.
643+--
644+-- For example,
645+--
646+-- >>> escapedFrameBy (== '{') (== '}') (== '\\') S.toList $ S.fromList "{hello}"
647+-- > "hello"
648+--
649+-- >>> escapedFrameBy (== '{') (== '}') (== '\\') S.toList $ S.fromList "{hello {world}}"
650+-- > "hello world"
651+--
652+-- >>> escapedFrameBy (== '{') (== '}') (== '\\') S.toList $ S.fromList "{hello \\{world\\}}"
653+-- > "hello {world}"
654+--
655+-- >>> escapedFrameBy (== '{') (== '}') (== '\\') S.toList $ S.fromList "{hello {world}"
656+-- > ParseError "Unterminated '{'"
657+--
658+-- /Unimplemented/
659+{-# INLINABLE escapedFrameBy #-}
660+escapedFrameBy :: -- MonadCatch m =>
661+ (a -> Bool) -> (a -> Bool) -> (a -> Bool) -> Fold m a b -> Parser m a b
662+escapedFrameBy _begin _end _escape _p = undefined
663+ -- D.toParserK . D.frameBy begin end escape p
664+
583-- | Like 'splitOn' but strips leading, trailing, and repeated separators.
665-- | Like 'splitOn' but strips leading, trailing, and repeated separators.
584-- Therefore, @".a..b."@ having '.' as the separator would be parsed as
666-- Therefore, @".a..b."@ having '.' as the separator would be parsed as
585-- @["a","b"]@. In other words, its like parsing words from whitespace
667-- @["a","b"]@. In other words, its like parsing words from whitespace