on master help sign in
Fix doc and naming of wordWithQuotes/blockWithQuotes
commit32785adf81d873e1e45885d223510e7defc3475c authorHarendra Kumar <harendra@composewell.com> dateWed 22 Feb 2023, 19:53 (4 years ago) parent77fd7f0
2 files changed+54−43
core/src/Streamly/Data/Parser.hs+2−2 core/src/Streamly/Internal/Data/Parser/ParserD.hs+52−41
core/src/Streamly/Data/Parser.hs+2−2
@@ -125,8 +125,8 @@ module Streamly.Data.Parser
125125 -- , groupByRollingEither
126126
127127 -- ** Framing
128− , wordFramedBy
129− , wordQuotedBy
128+ -- , wordFramedBy
129+ , wordWithQuotes
130130
131131 -- * Alternative
132132 , alt
core/src/Streamly/Internal/Data/Parser/ParserD.hs+52−41
@@ -145,8 +145,8 @@ module Streamly.Internal.Data.Parser.ParserD
145145 , takeFramedByEsc_
146146 , takeFramedByGeneric
147147 , wordFramedBy
148− , wordQuotedBy
149− , blockQuotedBy
148+ , wordWithQuotes
149+ , blockWithQuotes
150150
151151 -- Matching strings
152152 -- , prefixOf -- match any prefix of a given string
@@ -1504,7 +1504,7 @@ wordFramedBy :: Monad m =>
15041504 (a -> Bool) -- ^ Matches escape elem?
15051505 -> (a -> Bool) -- ^ Matches left quote?
15061506 -> (a -> Bool) -- ^ matches right quote?
1507− -> (a -> Bool) -- ^ matches word seperator?
1507+ -> (a -> Bool) -- ^ matches word separator?
15081508 -> Fold m a b
15091509 -> Parser a m b
15101510wordFramedBy isEsc isBegin isEnd isSep
@@ -1592,38 +1592,48 @@ data WordQuotedState s b a =
15921592-- XXX If quote start and end chars are different then quotes can be nested
15931593-- without escaping. However, is there a case for the use of nested quotes?
15941594
1595−-- XXX Simplify like blockQuotedBy
1595+-- XXX Simplify like blockWithQuotes
15961596
1597−-- | Like 'wordFramedBy' but the closing quote is determined by the opening
1598−-- quote. The first quote begin starts a quote that is closed by its
1599−-- corresponding closing quote.
1597+-- | Like 'wordBy' but word separators within quotes are ignored. Quote
1598+-- character can be used within quotes if escaped using the supplied escape
1599+-- char. A different quoting character can be used inside quotes without
1600+-- escaping. Starting quote determines the ending quote.
16001601--
1601−-- 'wordFramedBy' and 'wordQuotedBy' both allow multiple quote characters based
1602−-- on the predicates but 'wordQuotedBy' always fixes the quote at the first
1603−-- occurrence and then it is closed only by the corresponding closing quote.
1604−-- Therefore, other quoting characters can be embedded inside it as normal
1605−-- characters. On the other hand, 'wordFramedBy' would close the quote as soon
1606−-- as it encounters any of the closing quotes.
1602+-- Example:
16071603--
1608−-- >>> q = (`elem` ['"', '\''])
1609−-- >>> p kQ = Parser.wordQuotedBy kQ (== '\\') q q id isSpace Fold.toList
1604+-- >>> :{
1605+-- >>> lq x =
1606+-- >>> case x of
1607+-- >>> '"' -> Just x
1608+-- >>> '\'' -> Just x
1609+-- >>> _ -> Nothing
1610+-- >>> :}
1611+--
1612+-- >>> rq = (`elem` ['"', '\''])
1613+-- >>> p keep = Parser.wordWithQuotes keep (== '\\') lq rq isSpace Fold.toList
16101614--
16111615-- >>> Stream.parse (p False) $ Stream.fromList "a\"b'c\";'d\"e'f ghi"
16121616-- Right "ab'c;d\"ef"
16131617--
1618+-- Outer quotes and backslashes from the input string are removed by Haskell,
1619+-- therefore, the actual input string looks like:
1620+-- a"b'c";'d"e'f ghi
1621+-- From this the outer quotes are stripped by the parser, double quotes inside
1622+-- single quotes or vice-versa are kept.
1623+--
16141624-- >>> Stream.parse (p True) $ Stream.fromList "a\"b'c\";'d\"e'f ghi"
16151625-- Right "a\"b'c\";'d\"e'f"
16161626--
1617−{-# INLINE wordQuotedBy #-}
1618−wordQuotedBy :: (Monad m, Eq a) =>
1627+{-# INLINE wordWithQuotes #-}
1628+wordWithQuotes :: (Monad m, Eq a) =>
16191629 Bool -- ^ keep the quotes in the output
16201630 -> (a -> Bool) -- ^ Matches an escape elem?
16211631 -> (a -> Maybe a) -- ^ If left quote, return right quote, else nothing.
16221632 -> (a -> Bool) -- ^ Matches a right quote?
1623− -> (a -> Bool) -- ^ Matches a word seperator?
1633+ -> (a -> Bool) -- ^ Matches a word separator?
16241634 -> Fold m a b
16251635 -> Parser a m b
1626−wordQuotedBy keepQuotes isEsc toRight isEnd isSep
1636+wordWithQuotes keepQuotes isEsc toRight isEnd isSep
16271637 (Fold fstep finitial fextract) =
16281638 Parser step initial extract
16291639
@@ -1635,7 +1645,7 @@ wordQuotedBy keepQuotes isEsc toRight isEnd isSep
16351645 case res of
16361646 FL.Partial s -> IPartial (WordQuotedSkipPre s)
16371647 FL.Done _ ->
1638− error "wordQuotedBy: fold done without input"
1648+ error "wordWithQuotes: fold done without input"
16391649
16401650 {-# INLINE process #-}
16411651 process s a n ql qr = do
@@ -1664,7 +1674,7 @@ wordQuotedBy keepQuotes isEsc toRight isEnd isSep
16641674 else return $ Continue 0 $ WordQuotedWord s 1 a qr
16651675 Nothing
16661676 | isEnd a ->
1667− return $ Error "wordQuotedBy: missing frame start"
1677+ return $ Error "wordWithQuotes: missing frame start"
16681678 | otherwise -> processUnquoted s a
16691679 step (WordUnquotedWord s) a
16701680 | isEsc a = return $ Continue 0 $ WordUnquotedEsc s
@@ -1679,7 +1689,7 @@ wordQuotedBy keepQuotes isEsc toRight isEnd isSep
16791689 else return $ Continue 0 $ WordQuotedWord s 1 a qr
16801690 Nothing ->
16811691 if isEnd a
1682− then return $ Error "wordQuotedBy: missing frame start"
1692+ then return $ Error "wordWithQuotes: missing frame start"
16831693 else processUnquoted s a
16841694 step (WordQuotedWord s n ql qr) a
16851695 | isEsc a = return $ Continue 0 $ WordQuotedEsc s n ql qr
@@ -1713,11 +1723,11 @@ wordQuotedBy keepQuotes isEsc toRight isEnd isSep
17131723 extract (WordQuotedWord s n _ _) =
17141724 if n == 0
17151725 then fmap (Done 0) $ fextract s
1716− else err "wordQuotedBy: missing frame end"
1726+ else err "wordWithQuotes: missing frame end"
17171727 extract WordQuotedEsc {} =
1718− err "wordQuotedBy: trailing escape"
1728+ err "wordWithQuotes: trailing escape"
17191729 extract (WordUnquotedEsc _) =
1720− err "wordQuotedBy: trailing escape"
1730+ err "wordWithQuotes: trailing escape"
17211731 extract (WordQuotedSkipPost b) = return (Done 0 b)
17221732
17231733data BlockParseState s =
@@ -1733,26 +1743,27 @@ data BlockParseState s =
17331743
17341744-- XXX Put a limit on nest level to keep the API safe.
17351745
1736−-- | Parse a block using block enclosed by open, close identifiers, block
1737−-- identifiers inside quotes are ignored. Quoting characters can be escaped. A
1738−-- block can have a nested block inside it.
1746+-- | Parse a block enclosed within open, close brackets. Block contents may be
1747+-- quoted, brackets inside quotes are ignored. Quoting characters can be used
1748+-- within quotes if escaped. A block can have a nested block inside it.
17391749--
1740−-- Block chars and quote chars must not overlap. Block start and end chars must
1741−-- not be the same for nesting without escaping.
1750+-- Quote begin and end chars are the same. Block brackets and quote chars must
1751+-- not overlap. Block start and end brackets must be different for nesting
1752+-- blocks within blocks.
17421753--
1743−-- >>> p = Parser.blockQuotedBy '{' '}' '"' '\\' Fold.toList
1754+-- >>> p = Parser.blockWithQuotes '{' '}' '"' '\\' Fold.toList
17441755-- >>> Stream.parse p $ Stream.fromList "{msg: \"hello world\"}"
17451756-- Right "msg: \"hello world\""
17461757--
1747−{-# INLINE blockQuotedBy #-}
1748−blockQuotedBy :: (Monad m, Eq a) =>
1749− a -- ^ Block opening char
1750− -> a -- ^ Block closing char
1758+{-# INLINE blockWithQuotes #-}
1759+blockWithQuotes :: (Monad m, Eq a) =>
1760+ a -- ^ Block opening bracket
1761+ -> a -- ^ Block closing bracket
17511762 -> a -- ^ quote char
17521763 -> a -- ^ escape char
17531764 -> Fold m a b
17541765 -> Parser a m b
1755−blockQuotedBy bopen bclose quote esc
1766+blockWithQuotes bopen bclose quote esc
17561767 (Fold fstep finitial fextract) =
17571768 Parser step initial extract
17581769
@@ -1764,7 +1775,7 @@ blockQuotedBy bopen bclose quote esc
17641775 case res of
17651776 FL.Partial s -> IPartial (BlockInit s)
17661777 FL.Done _ ->
1767− error "wordQuotedBy: fold finished without input"
1778+ error "blockWithQuotes: fold finished without input"
17681779
17691780 {-# INLINE process #-}
17701781 process s a nextState = do
@@ -1778,7 +1789,7 @@ blockQuotedBy bopen bclose quote esc
17781789 return
17791790 $ if a == bopen
17801791 then Continue 0 $ BlockUnquoted 1 s
1781− else Error "blockQuotedBy: missing block start"
1792+ else Error "blockWithQuotes: missing block start"
17821793 step (BlockUnquoted level s) a =
17831794 if a == bopen
17841795 then process s a (BlockUnquoted (level + 1))
@@ -1804,12 +1815,12 @@ blockQuotedBy bopen bclose quote esc
18041815
18051816 extract (BlockInit s) = fmap (Done 0) $ fextract s
18061817 extract (BlockUnquoted level _) =
1807− err $ "blockQuotedBy: finished at block nest level " ++ show level
1818+ err $ "blockWithQuotes: finished at block nest level " ++ show level
18081819 extract (BlockQuoted level _) =
1809− err $ "blockQuotedBy: finished, inside an unfinished quote, "
1820+ err $ "blockWithQuotes: finished, inside an unfinished quote, "
18101821 ++ "at block nest level " ++ show level
18111822 extract (BlockQuotedEsc level _) =
1812− err $ "blockQuotedBy: finished, inside an unfinished quote, "
1823+ err $ "blockWithQuotes: finished, inside an unfinished quote, "
18131824 ++ "after an escape char, at block nest level " ++ show level
18141825
18151826{-# ANN type GroupByState Fuse #-}