@@ -111,6 +111,7 @@ module Streamly.Internal.Data.Parser.ParserD
111111 -- Use two folds, run a primary parser, its rejected values go to the
112112 -- secondary parser.
113113 , deintercalate
114+ , sepBy
114115
115116 -- ** Sequential Alternative
116117 , alt
@@ -1258,6 +1259,76 @@ deintercalate ::
12581259 -> Parser m x (y, z)
12591260deintercalate = undefined
12601261
1262+data SepByState fs sp ss =
1263+ SepByInit fs sp
1264+ | SepBySeparator fs ss Bool
1265+
1266+{-# INLINE sepBy #-}
1267+sepBy :: MonadCatch m =>
1268+ Fold m b c -> Parser m a b -> Parser m a x -> Parser m a c
1269+sepBy
1270+ (Fold fstep finitial fextract)
1271+ (Parser pstep pinitial pextract)
1272+ (Parser sstep sinitial _) = Parser step initial extract
1273+
1274+ where
1275+
1276+ errMsg p status =
1277+ error $ "sepBy: " ++ p ++ " parser cannot "
1278+ ++ status ++ " without input"
1279+
1280+ initial = do
1281+ res <- finitial
1282+ case res of
1283+ FL.Partial fs -> do
1284+ resP <- pinitial
1285+ case resP of
1286+ IPartial sp -> return $ IPartial $ SepByInit fs sp
1287+ IDone _ -> errMsg "content" "succeed"
1288+ IError _ -> errMsg "content" "fail"
1289+ FL.Done b -> return $ IDone b
1290+
1291+ step (SepByInit fs sp) a = do
1292+ r <- pstep sp a
1293+ case r of
1294+ Partial n s -> return $ Partial n (SepByInit fs s)
1295+ Continue n s -> return $ Continue n (SepByInit fs s)
1296+ Done n b -> do
1297+ fres <- fstep fs b
1298+ case fres of
1299+ FL.Partial fs1 -> do
1300+ resS <- sinitial
1301+ case resS of
1302+ IPartial ss ->
1303+ return $ Partial n (SepBySeparator fs1 ss False)
1304+ IDone _ -> errMsg "separator" "succeed"
1305+ IError _ -> errMsg "separator" "fail"
1306+ FL.Done c -> return $ Done n c
1307+ Error err -> return $ Error err
1308+ step (SepBySeparator fs ss consumed) a = do
1309+ r <- sstep ss a
1310+ case r of
1311+ Partial n s -> return $ Partial n (SepBySeparator fs s True)
1312+ Continue n s -> return $ Continue n (SepBySeparator fs s True)
1313+ Done n _ ->
1314+ if consumed
1315+ then do
1316+ resP <- pinitial
1317+ case resP of
1318+ IPartial sp -> return $ Partial n $ SepByInit fs sp
1319+ IDone _ -> errMsg "content" "succeed"
1320+ IError _ -> errMsg "content" "fail"
1321+ else return $ Error "sepBy: infinite loop"
1322+ Error err -> return $ Error err
1323+
1324+ extract (SepByInit fs sp) = do
1325+ r <- pextract sp
1326+ res <- fstep fs r
1327+ case res of
1328+ FL.Partial fs1 -> fextract fs1
1329+ FL.Done c -> return c
1330+ extract (SepBySeparator fs _ _) = fextract fs
1331+
12611332-------------------------------------------------------------------------------
12621333-- Sequential Collection
12631334-------------------------------------------------------------------------------