on master help sign in
Implement deintercalate parser
0ff46e4Harendra Kumar
core/src/Streamly/Internal/Data/Parser.hs+15−9
@@ -240,7 +240,7 @@ import qualified Streamly.Internal.Data.Parser.ParserK.Type as K
240-- >>> import Control.Applicative ((<|>))
240-- >>> import Control.Applicative ((<|>))
241-- >>> import qualified Streamly.Prelude as Stream
241-- >>> import qualified Streamly.Prelude as Stream
242-- >>> import qualified Streamly.Internal.Data.Stream.IsStream as Stream (parse, parseMany)
242-- >>> import qualified Streamly.Internal.Data.Stream.IsStream as Stream (parse, parseMany)
243−-- >>> import qualified Streamly.Data.Fold as Fold
243+-- >>> import qualified Streamly.Internal.Data.Fold as Fold
244-- >>> import qualified Streamly.Internal.Data.Parser as Parser
244-- >>> import qualified Streamly.Internal.Data.Parser as Parser
245
245
246-------------------------------------------------------------------------------
246-------------------------------------------------------------------------------
@@ -1257,22 +1257,26 @@ manyThen _parser _recover _f = undefined
1257-- front of the pattern. When a match occurs we need to emit the accumulator of
1257-- front of the pattern. When a match occurs we need to emit the accumulator of
1258-- all the three parsers. One parser can count the line numbers to provide the
1258-- all the three parsers. One parser can count the line numbers to provide the
1259-- line number info.
1259-- line number info.
1260−--
1260+
1261+-- XXX rename this to intercalate
1261-- | Apply two parsers alternately to an input stream. The input stream is
1262-- | Apply two parsers alternately to an input stream. The input stream is
1262-- considered an interleaving of two patterns. The two parsers represent the
1263-- considered an interleaving of two patterns. The two parsers represent the
1263-- two patterns.
1264-- two patterns.
1264--
1265--
1265-- This undoes a "gintercalate" of two streams.
1266-- This undoes a "gintercalate" of two streams.
1266--
1267--
1267−-- /Unimplemented/
1268+-- /Pre-release/
1268--
1269--
1269{-# INLINE deintercalate #-}
1270{-# INLINE deintercalate #-}
1270−deintercalate ::
1271+deintercalate :: MonadCatch m =>
1271− -- Monad m =>
1272+ Fold m (Either x y) z
1272− Fold m a y -> Parser m x a
1273+ -> Parser m a x
1273− -> Fold m b z -> Parser m x b
1274+ -> Parser m a y
1274− -> Parser m x (y, z)
1275+ -> Parser m a z
1275−deintercalate = undefined
1276+deintercalate sink contentL contentR =
1277+ D.toParserK
1278+ $ D.deintercalate
1279+ sink (D.fromParserK contentL) (D.fromParserK contentR)
1276
1280
1277-- | Parse items separated by a separator parsed by the supplied parser. At
1281-- | Parse items separated by a separator parsed by the supplied parser. At
1278-- least one item must be present for the parser to succeed.
1282-- least one item must be present for the parser to succeed.
@@ -1293,6 +1297,7 @@ sepBy1 sink p sep = do
1293-- run, when it is done content parser is run again and so on. If none of the
1297-- run, when it is done content parser is run again and so on. If none of the
1294-- parsers consumes an input then parser returns a failure.
1298-- parsers consumes an input then parser returns a failure.
1295--
1299--
1300+-- >>> sepBy sink = Parser.deintercalate (Fold.lefts sink)
1296-- >>> sepBy sink content sep = Parser.sepBy1 sink content sep <|> return mempty
1301-- >>> sepBy sink content sep = Parser.sepBy1 sink content sep <|> return mempty
1297--
1302--
1298{-# INLINE sepBy #-}
1303{-# INLINE sepBy #-}
@@ -1300,6 +1305,7 @@ sepBy :: MonadCatch m =>
1300 Fold m b c -> Parser m a b -> Parser m a x -> Parser m a c
1305 Fold m b c -> Parser m a b -> Parser m a x -> Parser m a c
1301sepBy sink content sep =
1306sepBy sink content sep =
1302 D.toParserK $ D.sepBy sink (D.fromParserK content) (D.fromParserK sep)
1307 D.toParserK $ D.sepBy sink (D.fromParserK content) (D.fromParserK sep)
1308+-- sepBy sink = deintercalate (FL.lefts sink)
1303
1309
1304-------------------------------------------------------------------------------
1310-------------------------------------------------------------------------------
1305-- Interleaving a collection of parsers
1311-- Interleaving a collection of parsers
core/src/Streamly/Internal/Data/Parser/ParserD.hs+86−8
@@ -1246,23 +1246,101 @@ lookAhead (Parser step1 initial1 _) = Parser step initial extract
1246-------------------------------------------------------------------------------
1246-------------------------------------------------------------------------------
1247-- Interleaving
1247-- Interleaving
1248-------------------------------------------------------------------------------
1248-------------------------------------------------------------------------------
1249−--
1249+
1250+data DeintercalateState fs sp ss =
1251+ DeintercalateL fs sp
1252+ | DeintercalateR fs ss Bool
1253+
1250-- | See 'Streamly.Internal.Data.Parser.deintercalate'.
1254-- | See 'Streamly.Internal.Data.Parser.deintercalate'.
1251--
1255--
1252−-- /Unimplemented/
1256+-- /Internal/
1253--
1257--
1254{-# INLINE deintercalate #-}
1258{-# INLINE deintercalate #-}
1255−deintercalate ::
1259+deintercalate :: Monad m =>
1256− -- Monad m =>
1260+ Fold m (Either x y) z
1257− Fold m a y -> Parser m x a
1261+ -> Parser m a x
1258− -> Fold m b z -> Parser m x b
1262+ -> Parser m a y
1259− -> Parser m x (y, z)
1263+ -> Parser m a z
1260−deintercalate = undefined
1264+deintercalate
1265+ (Fold fstep finitial fextract)
1266+ (Parser stepL initialL extractL)
1267+ (Parser stepR initialR extractR) = Parser step initial extract
1268+
1269+ where
1270+
1271+ errMsg p status =
1272+ error $ "sepBy: " ++ p ++ " parser cannot "
1273+ ++ status ++ " without input"
1274+
1275+ initial = do
1276+ res <- finitial
1277+ case res of
1278+ FL.Partial fs -> do
1279+ resL <- initialL
1280+ case resL of
1281+ IPartial sL -> return $ IPartial $ DeintercalateL fs sL
1282+ IDone _ -> errMsg "left" "succeed"
1283+ IError _ -> errMsg "left" "fail"
1284+ FL.Done c -> return $ IDone c
1285+
1286+ step (DeintercalateL fs sL) a = do
1287+ r <- stepL sL a
1288+ case r of
1289+ Partial n s -> return $ Partial n (DeintercalateL fs s)
1290+ Continue n s -> return $ Continue n (DeintercalateL fs s)
1291+ Done n b -> do
1292+ fres <- fstep fs (Left b)
1293+ case fres of
1294+ FL.Partial fs1 -> do
1295+ resR <- initialR
1296+ case resR of
1297+ IPartial sR ->
1298+ return
1299+ $ Partial n (DeintercalateR fs1 sR False)
1300+ IDone _ -> errMsg "right" "succeed"
1301+ IError _ -> errMsg "right" "fail"
1302+ FL.Done c -> return $ Done n c
1303+ Error err -> return $ Error err
1304+ step (DeintercalateR fs sR consumed) a = do
1305+ r <- stepR sR a
1306+ case r of
1307+ Partial n s -> return $ Partial n (DeintercalateR fs s True)
1308+ Continue n s -> return $ Continue n (DeintercalateR fs s True)
1309+ Done n b ->
1310+ if consumed
1311+ then do
1312+ fres <- fstep fs (Right b)
1313+ case fres of
1314+ FL.Partial fs1 -> do
1315+ resL <- initialL
1316+ case resL of
1317+ IPartial sL ->
1318+ return $ Partial n $ DeintercalateL fs1 sL
1319+ IDone _ -> errMsg "left" "succeed"
1320+ IError _ -> errMsg "left" "fail"
1321+ FL.Done c -> return $ Done n c
1322+ else return $ Error "sepBy: infinite loop"
1323+ Error err -> return $ Error err
1324+
1325+ extract (DeintercalateL fs sL) = do
1326+ r <- extractL sL
1327+ res <- fstep fs (Left r)
1328+ case res of
1329+ FL.Partial fs1 -> fextract fs1
1330+ FL.Done c -> return c
1331+ extract (DeintercalateR fs sR _) = do
1332+ r <- extractR sR
1333+ res <- fstep fs (Right r)
1334+ case res of
1335+ FL.Partial fs1 -> fextract fs1
1336+ FL.Done c -> return c
1261
1337
1262data SepByState fs sp ss =
1338data SepByState fs sp ss =
1263 SepByInit fs sp
1339 SepByInit fs sp
1264 | SepBySeparator fs ss Bool
1340 | SepBySeparator fs ss Bool
1265
1341
1342+-- This is a special case of deintercalate and can be easily implemented in
1343+-- terms of deintercalate.
1266{-# INLINE sepBy #-}
1344{-# INLINE sepBy #-}
1267sepBy :: MonadCatch m =>
1345sepBy :: MonadCatch m =>
1268 Fold m b c -> Parser m a b -> Parser m a x -> Parser m a c
1346 Fold m b c -> Parser m a b -> Parser m a x -> Parser m a c