on master help sign in
Add sepBy1 and sepBy
7f38a19Harendra Kumar
core/src/Streamly/Internal/Data/Parser.hs+58−37
@@ -165,7 +165,8 @@ module Streamly.Internal.Data.Parser
165 --
165 --
166 -- @
166 -- @
167 -- , endBy
167 -- , endBy
168+ , sepBy1
168− -- , sepBy
169+ , sepBy
169 -- , sepEndBy
170 -- , sepEndBy
170 -- , beginBy
171 -- , beginBy
171 -- , sepBeginBy
172 -- , sepBeginBy
@@ -206,6 +207,7 @@ module Streamly.Internal.Data.Parser
206 )
207 )
207where
208where
208
209
210+import Control.Applicative ((<|>))
209import Control.Monad.Catch (MonadCatch, MonadThrow)
211import Control.Monad.Catch (MonadCatch, MonadThrow)
210import Prelude hiding
212import Prelude hiding
211 (any, all, take, takeWhile, sequence, concatMap, maybe, either, filter)
213 (any, all, take, takeWhile, sequence, concatMap, maybe, either, filter)
@@ -764,6 +766,8 @@ groupByRollingEither :: MonadCatch m =>
764 (a -> a -> Bool) -> Fold m a b -> Fold m a c -> Parser m a (Either b c)
766 (a -> a -> Bool) -> Fold m a b -> Fold m a c -> Parser m a (Either b c)
765groupByRollingEither eq f1 = D.toParserK . D.groupByRollingEither eq f1
767groupByRollingEither eq f1 = D.toParserK . D.groupByRollingEither eq f1
766
768
769+-- XXX Use a stream instead of a list so that we can use any container type.
770+
767-- | Match the given sequence of elements using the given comparison function.
771-- | Match the given sequence of elements using the given comparison function.
768--
772--
769-- >>> Stream.parse (Parser.eqBy (==) "string") $ Stream.fromList "string"
773-- >>> Stream.parse (Parser.eqBy (==) "string") $ Stream.fromList "string"
@@ -954,42 +958,6 @@ lookAhead p = D.toParserK $ D.lookAhead $ D.fromParserK p
954takeP :: MonadCatch m => Int -> Parser m a b -> Parser m a b
958takeP :: MonadCatch m => Int -> Parser m a b -> Parser m a b
955takeP i p = D.toParserK $ D.takeP i $ D.fromParserK p
959takeP i p = D.toParserK $ D.takeP i $ D.fromParserK p
956
960
957−-------------------------------------------------------------------------------
958−-- Interleaving
959−-------------------------------------------------------------------------------
960−--
961−-- To deinterleave we can chain two parsers one behind the other. The input is
962−-- given to the first parser and the input definitively rejected by the first
963−-- parser is given to the second parser.
964−--
965−-- We can either have the parsers themselves buffer the input or use the shared
966−-- global buffer to hold it until none of the parsers need it. When the first
967−-- parser returns Skip (i.e. rewind) we let the second parser consume the
968−-- rejected input and when it is done we move the cursor forward to the first
969−-- parser again. This will require a "move forward" command as well.
970−--
971−-- To implement grep we can use three parsers, one to find the pattern, one
972−-- to store the context behind the pattern and one to store the context in
973−-- front of the pattern. When a match occurs we need to emit the accumulator of
974−-- all the three parsers. One parser can count the line numbers to provide the
975−-- line number info.
976−--
977−-- | Apply two parsers alternately to an input stream. The input stream is
978−-- considered an interleaving of two patterns. The two parsers represent the
979−-- two patterns.
980−--
981−-- This undoes a "gintercalate" of two streams.
982−--
983−-- /Unimplemented/
984−--
985−{-# INLINE deintercalate #-}
986−deintercalate ::
987− -- Monad m =>
988− Fold m a y -> Parser m x a
989− -> Fold m b z -> Parser m x b
990− -> Parser m x (y, z)
991−deintercalate = undefined
992−
993-------------------------------------------------------------------------------
961-------------------------------------------------------------------------------
994-- Sequential Collection
962-- Sequential Collection
995-------------------------------------------------------------------------------
963-------------------------------------------------------------------------------
@@ -1168,6 +1136,59 @@ manyThen :: -- (Foldable t, MonadCatch m) =>
1168 Parser m a b -> Parser m a x -> Fold m b c -> Parser m a c
1136 Parser m a b -> Parser m a x -> Fold m b c -> Parser m a c
1169manyThen _parser _recover _f = undefined
1137manyThen _parser _recover _f = undefined
1170
1138
1139+-------------------------------------------------------------------------------
1140+-- Interleaving
1141+-------------------------------------------------------------------------------
1142+--
1143+-- To deinterleave we can chain two parsers one behind the other. The input is
1144+-- given to the first parser and the input definitively rejected by the first
1145+-- parser is given to the second parser.
1146+--
1147+-- We can either have the parsers themselves buffer the input or use the shared
1148+-- global buffer to hold it until none of the parsers need it. When the first
1149+-- parser returns Skip (i.e. rewind) we let the second parser consume the
1150+-- rejected input and when it is done we move the cursor forward to the first
1151+-- parser again. This will require a "move forward" command as well.
1152+--
1153+-- To implement grep we can use three parsers, one to find the pattern, one
1154+-- to store the context behind the pattern and one to store the context in
1155+-- front of the pattern. When a match occurs we need to emit the accumulator of
1156+-- all the three parsers. One parser can count the line numbers to provide the
1157+-- line number info.
1158+--
1159+-- | Apply two parsers alternately to an input stream. The input stream is
1160+-- considered an interleaving of two patterns. The two parsers represent the
1161+-- two patterns.
1162+--
1163+-- This undoes a "gintercalate" of two streams.
1164+--
1165+-- /Unimplemented/
1166+--
1167+{-# INLINE deintercalate #-}
1168+deintercalate ::
1169+ -- Monad m =>
1170+ Fold m a y -> Parser m x a
1171+ -> Fold m b z -> Parser m x b
1172+ -> Parser m x (y, z)
1173+deintercalate = undefined
1174+
1175+-- | Parse items separated by a separator parsed by the supplied parser. At
1176+-- least one item must be present for the parser to succeed.
1177+{-# INLINE sepBy1 #-}
1178+sepBy1 :: MonadCatch m =>
1179+ Fold m b c -> Parser m a b -> Parser m a x -> Parser m a c
1180+sepBy1 sink p sep = do
1181+ x <- p
1182+ f <- fromEffect $ FL.initialize sink
1183+ f1 <- fromEffect $ FL.snoc f x
1184+ many (sep >> p) f1
1185+
1186+-- | sepBy1 or empty, does not fail.
1187+{-# INLINE sepBy #-}
1188+sepBy :: (MonadCatch m, Monoid c) =>
1189+ Fold m b c -> Parser m a b -> Parser m a x -> Parser m a c
1190+sepBy sink p sep = sepBy1 sink p sep <|> return mempty
1191+
1171-------------------------------------------------------------------------------
1192-------------------------------------------------------------------------------
1172-- Interleaving a collection of parsers
1193-- Interleaving a collection of parsers
1173-------------------------------------------------------------------------------
1194-------------------------------------------------------------------------------