on master help sign in
Add skeleton for some unimplemented parsers
commit9b511beeb5b06a33b238332e6452b52d40eedbf4 authorHarendra Kumar <harendra@composewell.com> dateFri 17 Jul 2020, 18:32 (6 years ago) parentf0398ee
1 file changed+117−35
src/Streamly/Internal/Data/Parser.hs+117−35
src/Streamly/Internal/Data/Parser.hs+117−35
@@ -72,56 +72,29 @@ module Streamly.Internal.Data.Parser
7272 --
7373 -- | Parsers chained in series, if one parser terminates the composition
7474 -- 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.
8975
9076 -- | Grab a sequence of input elements without inspecting them
91− , take
77+ , takeBetween
78+ , take -- takeBetween 0 n
9279 -- $take
93− -- | Unimplemented
94− --
95− -- @
96− -- , takeBetween
97− -- , takeLE -- take -- takeBetween 0 n
98− -- , takeLE1 -- take1 -- takeBetween 1 n
99− -- @
10080 , takeEQ -- takeBetween n n
10181 , takeGE -- takeBetween n maxBound
10282
10383 -- Grab a sequence of input elements by inspecting them
10484 , lookAhead
85+ , takeWhileP
10586 , takeWhile
10687 -- $takeWhile
10788 , takeWhile1
89+
90+ , sliceSepByP
10891 , sliceSepBy
10992 , sliceSepByMax
110− -- | Unimplemented
111− --
112− -- @
113− -- , sliceSepByBetween
114− -- @
11593 , sliceEndWith
11694 , sliceBeginWith
117− -- | Unimplemented
118− --
119− -- @
120− -- , sliceSepWith
121− --
122− -- , frameSepBy -- parse frames escaped by an escape char/sequence
123− -- , frameEndWith
124− -- @
95+ , sliceSepWith
96+ , escapedSliceSepBy
97+ , escapedFrameBy
12598 , wordBy
12699 , groupBy
127100 , eqBy
@@ -365,6 +338,30 @@ satisfy = D.toParserK . D.satisfy
365338-------------------------------------------------------------------------------
366339-- Taking elements
367340-------------------------------------------------------------------------------
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+
368365--
369366-- $take
370367-- Note: this is called takeP in some parser libraries.
@@ -428,6 +425,27 @@ takeGE n = D.toParserK . D.takeGE n
428425-- $takeWhile
429426-- Note: This is called @takeWhileP@ and @munch@ in some parser libraries.
430427
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+
431449-- | Collect stream elements until an element fails the predicate. The element
432450-- on which the predicate fails is returned back to the input stream.
433451--
@@ -457,6 +475,25 @@ takeWhile cond = D.toParserK . D.takeWhile cond
457475takeWhile1 :: MonadCatch m => (a -> Bool) -> Fold m a b -> Parser m a b
458476takeWhile1 cond = D.toParserK . D.takeWhile1 cond
459477
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+
460497-- Note: Keep this consistent with S.splitOn. In fact we should eliminate
461498-- S.splitOn in favor of the parser.
462499--
@@ -506,6 +543,15 @@ takeWhile1 cond = D.toParserK . D.takeWhile1 cond
506543sliceSepBy :: MonadCatch m => (a -> Bool) -> Fold m a b -> Parser m a b
507544sliceSepBy cond = D.toParserK . D.sliceSepBy cond
508545
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+
509555-- | Collect stream elements until an element succeeds the predicate. Also take
510556-- the element on which the predicate succeeded. The succeeding element is
511557-- treated as a suffix separator which is kept in the output segement.
@@ -580,6 +626,42 @@ sliceSepByMax :: MonadCatch m
580626 => (a -> Bool) -> Int -> Fold m a b -> Parser m a b
581627sliceSepByMax cond cnt = D.toParserK . D.sliceSepByMax cond cnt
582628
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+
583665-- | Like 'splitOn' but strips leading, trailing, and repeated separators.
584666-- Therefore, @".a..b."@ having '.' as the separator would be parsed as
585667-- @["a","b"]@. In other words, its like parsing words from whitespace