on master help sign in
Implement deintercalate parser
commit0ff46e4a7636b43ffa828ef780c2cf5f64b3aa28 authorHarendra Kumar <harendra@composewell.com> dateFri 6 May 2022, 14:43 (4 years ago) parentc94f540
2 files changed+101−17
core/src/Streamly/Internal/Data/Parser.hs+15−9 core/src/Streamly/Internal/Data/Parser/ParserD.hs+86−8
core/src/Streamly/Internal/Data/Parser.hs+15−9
@@ -240,7 +240,7 @@ import qualified Streamly.Internal.Data.Parser.ParserK.Type as K
240240-- >>> import Control.Applicative ((<|>))
241241-- >>> import qualified Streamly.Prelude as Stream
242242-- >>> 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
244244-- >>> import qualified Streamly.Internal.Data.Parser as Parser
245245
246246-------------------------------------------------------------------------------
@@ -1257,22 +1257,26 @@ manyThen _parser _recover _f = undefined
12571257-- front of the pattern. When a match occurs we need to emit the accumulator of
12581258-- all the three parsers. One parser can count the line numbers to provide the
12591259-- line number info.
1260−--
1260+
1261+-- XXX rename this to intercalate
12611262-- | Apply two parsers alternately to an input stream. The input stream is
12621263-- considered an interleaving of two patterns. The two parsers represent the
12631264-- two patterns.
12641265--
12651266-- This undoes a "gintercalate" of two streams.
12661267--
1267−-- /Unimplemented/
1268+-- /Pre-release/
12681269--
12691270{-# INLINE deintercalate #-}
1270−deintercalate ::
1271− -- Monad m =>
1272− Fold m a y -> Parser m x a
1273− -> Fold m b z -> Parser m x b
1274− -> Parser m x (y, z)
1275−deintercalate = undefined
1271+deintercalate :: MonadCatch m =>
1272+ Fold m (Either x y) z
1273+ -> Parser m a x
1274+ -> Parser m a y
1275+ -> Parser m a z
1276+deintercalate sink contentL contentR =
1277+ D.toParserK
1278+ $ D.deintercalate
1279+ sink (D.fromParserK contentL) (D.fromParserK contentR)
12761280
12771281-- | Parse items separated by a separator parsed by the supplied parser. At
12781282-- least one item must be present for the parser to succeed.
@@ -1293,6 +1297,7 @@ sepBy1 sink p sep = do
12931297-- run, when it is done content parser is run again and so on. If none of the
12941298-- parsers consumes an input then parser returns a failure.
12951299--
1300+-- >>> sepBy sink = Parser.deintercalate (Fold.lefts sink)
12961301-- >>> sepBy sink content sep = Parser.sepBy1 sink content sep <|> return mempty
12971302--
12981303{-# INLINE sepBy #-}
@@ -1300,6 +1305,7 @@ sepBy :: MonadCatch m =>
13001305 Fold m b c -> Parser m a b -> Parser m a x -> Parser m a c
13011306sepBy sink content sep =
13021307 D.toParserK $ D.sepBy sink (D.fromParserK content) (D.fromParserK sep)
1308+-- sepBy sink = deintercalate (FL.lefts sink)
13031309
13041310-------------------------------------------------------------------------------
13051311-- 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
12461246-------------------------------------------------------------------------------
12471247-- Interleaving
12481248-------------------------------------------------------------------------------
1249−--
1249+
1250+data DeintercalateState fs sp ss =
1251+ DeintercalateL fs sp
1252+ | DeintercalateR fs ss Bool
1253+
12501254-- | See 'Streamly.Internal.Data.Parser.deintercalate'.
12511255--
1252−-- /Unimplemented/
1256+-- /Internal/
12531257--
12541258{-# INLINE deintercalate #-}
1255−deintercalate ::
1256− -- Monad m =>
1257− Fold m a y -> Parser m x a
1258− -> Fold m b z -> Parser m x b
1259− -> Parser m x (y, z)
1260−deintercalate = undefined
1259+deintercalate :: Monad m =>
1260+ Fold m (Either x y) z
1261+ -> Parser m a x
1262+ -> Parser m a y
1263+ -> Parser m a z
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
12611337
12621338data SepByState fs sp ss =
12631339 SepByInit fs sp
12641340 | SepBySeparator fs ss Bool
12651341
1342+-- This is a special case of deintercalate and can be easily implemented in
1343+-- terms of deintercalate.
12661344{-# INLINE sepBy #-}
12671345sepBy :: MonadCatch m =>
12681346 Fold m b c -> Parser m a b -> Parser m a x -> Parser m a c