@@ -47,6 +47,8 @@ module Streamly.Internal.Data.StreamK
4747 , parseD
4848 , parseBreakChunks
4949 , parseChunks
50+ , parseBreakSingular
51+ , parseSingular
5052
5153 -- ** Specialized Folds
5254 , head
@@ -1424,6 +1426,135 @@ parseChunks :: (Monad m, Unbox a) =>
14241426 ParserK (Array a) m b -> StreamK m (Array a) -> m (Either ParseError b)
14251427parseChunks f = fmap fst . parseBreakChunks f
14261428
1429+-------------------------------------------------------------------------------
1430+-- Parsing using ParserK.Generic
1431+-------------------------------------------------------------------------------
1432+
1433+{-# INLINE backTrackSingular #-}
1434+backTrackSingular :: Int -> [a] -> StreamK m a -> (StreamK m a, [a])
1435+backTrackSingular = go
1436+
1437+ where
1438+
1439+ go _ [] stream = (stream, [])
1440+ go n xs stream | n <= 0 = (stream, xs)
1441+ go n xs stream =
1442+ let (appendBuf, newBTBuf) = splitAt n xs
1443+ in (append (fromList (Prelude.reverse appendBuf)) stream, newBTBuf)
1444+
1445+
1446+-- | Similar to 'parseBreak' but works on singular elements.
1447+--
1448+{-# INLINE_NORMAL parseBreakSingular #-}
1449+parseBreakSingular
1450+ :: forall m a b. Monad m
1451+ => ParserK.ParserK a m b
1452+ -> StreamK m a
1453+ -> m (Either ParseError b, StreamK m a)
1454+parseBreakSingular parser input = do
1455+ let parserk = ParserK.runParser parser parserDone 0 0
1456+ in go [] parserk input
1457+
1458+ where
1459+
1460+ {-# INLINE goStop #-}
1461+ goStop
1462+ :: [a]
1463+ -> (ParserK.Input a -> m (ParserK.Step a m b))
1464+ -> m (Either ParseError b, StreamK m a)
1465+ goStop backBuf parserk = do
1466+ pRes <- parserk ParserK.None
1467+ case pRes of
1468+ -- If we stop in an alternative, it will try calling the next
1469+ -- parser, the next parser may call initial returning Partial and
1470+ -- then immediately we have to call extract on it.
1471+ ParserK.Partial 0 cont1 ->
1472+ go [] cont1 nil
1473+ ParserK.Partial n cont1 -> do
1474+ let n1 = negate n
1475+ assertM(n1 >= 0 && n1 <= length backBuf)
1476+ let (s1, backBuf1) = backTrackSingular n1 backBuf nil
1477+ in go backBuf1 cont1 s1
1478+ ParserK.Continue 0 cont1 ->
1479+ go backBuf cont1 nil
1480+ ParserK.Continue n cont1 -> do
1481+ let n1 = negate n
1482+ assertM(n1 >= 0 && n1 <= length backBuf)
1483+ let (s1, backBuf1) = backTrackSingular n1 backBuf nil
1484+ in go backBuf1 cont1 s1
1485+ ParserK.Done 0 b ->
1486+ return (Right b, nil)
1487+ ParserK.Done n b -> do
1488+ let n1 = negate n
1489+ assertM(n1 >= 0 && n1 <= length backBuf)
1490+ let (s1, _) = backTrackSingular n1 backBuf nil
1491+ in return (Right b, s1)
1492+ ParserK.Error _ err -> return (Left (ParseError err), nil)
1493+
1494+ seekErr n =
1495+ error $ "parseBreakSingular: Partial: forward seek not implemented n = "
1496+ ++ show n
1497+
1498+ yieldk
1499+ :: [a]
1500+ -> (ParserK.Input a -> m (ParserK.Step a m b))
1501+ -> a
1502+ -> StreamK m a
1503+ -> m (Either ParseError b, StreamK m a)
1504+ yieldk backBuf parserk arr stream = do
1505+ pRes <- parserk (ParserK.Chunk arr)
1506+ case pRes of
1507+ ParserK.Partial 1 cont1 -> go [] cont1 stream
1508+ ParserK.Partial 0 cont1 -> go [] cont1 (cons arr stream)
1509+ ParserK.Partial n _ | n > 1 -> seekErr n
1510+ ParserK.Partial n cont1 -> do
1511+ let n1 = negate n
1512+ bufLen = length backBuf
1513+ s = cons arr stream
1514+ assertM(n1 >= 0 && n1 <= bufLen)
1515+ let (s1, _) = backTrackSingular n1 backBuf s
1516+ go [] cont1 s1
1517+ ParserK.Continue 1 cont1 -> go (arr:backBuf) cont1 stream
1518+ ParserK.Continue 0 cont1 ->
1519+ go backBuf cont1 (cons arr stream)
1520+ ParserK.Continue n _ | n > 1 -> seekErr n
1521+ ParserK.Continue n cont1 -> do
1522+ let n1 = negate n
1523+ bufLen = length backBuf
1524+ s = cons arr stream
1525+ assertM(n1 >= 0 && n1 <= bufLen)
1526+ let (s1, backBuf1) = backTrackSingular n1 backBuf s
1527+ go backBuf1 cont1 s1
1528+ ParserK.Done 1 b -> pure (Right b, stream)
1529+ ParserK.Done 0 b -> pure (Right b, cons arr stream)
1530+ ParserK.Done n _ | n > 1 -> seekErr n
1531+ ParserK.Done n b -> do
1532+ let n1 = negate n
1533+ bufLen = length backBuf
1534+ s = cons arr stream
1535+ assertM(n1 >= 0 && n1 <= bufLen)
1536+ let (s1, _) = backTrackSingular n1 backBuf s
1537+ pure (Right b, s1)
1538+ ParserK.Error _ err -> return (Left (ParseError err), nil)
1539+
1540+ go
1541+ :: [a]
1542+ -> (ParserK.Input a -> m (ParserK.Step a m b))
1543+ -> StreamK m a
1544+ -> m (Either ParseError b, StreamK m a)
1545+ go backBuf parserk stream = do
1546+ let stop = goStop backBuf parserk
1547+ single a = yieldk backBuf parserk a nil
1548+ in foldStream
1549+ defState (yieldk backBuf parserk) single stop stream
1550+
1551+-- | Run a 'ParserK' over a 'StreamK'. Please use 'parseChunks' where possible,
1552+-- for better performance.
1553+{-# INLINE parseSingular #-}
1554+parseSingular :: Monad m =>
1555+ ParserK.ParserK a m b -> StreamK m a -> m (Either ParseError b)
1556+parseSingular f = fmap fst . parseBreakSingular f
1557+
14271558-------------------------------------------------------------------------------
14281559-- Sorting
14291560-------------------------------------------------------------------------------