From 5658b5b5193949fbea27ee1b6e819307120bc076 Mon Sep 17 00:00:00 2001 From: Favonia Date: Wed, 23 Sep 2015 12:32:42 -0400 Subject: [PATCH 1/6] Add skipTill and skipTill' --- Data/Attoparsec/ByteString.hs | 2 ++ Data/Attoparsec/ByteString/Char8.hs | 2 ++ Data/Attoparsec/Combinator.hs | 30 +++++++++++++++++++++++++++++ Data/Attoparsec/Text.hs | 2 ++ 4 files changed, 36 insertions(+) diff --git a/Data/Attoparsec/ByteString.hs b/Data/Attoparsec/ByteString.hs index 84e567d9..bcd0e438 100644 --- a/Data/Attoparsec/ByteString.hs +++ b/Data/Attoparsec/ByteString.hs @@ -89,6 +89,8 @@ module Data.Attoparsec.ByteString , sepBy1' , skipMany , skipMany1 + , skipTill + , skipTill' , eitherP , I.match -- * State observation and manipulation functions diff --git a/Data/Attoparsec/ByteString/Char8.hs b/Data/Attoparsec/ByteString/Char8.hs index 4f1fecbd..a9a9cd7f 100644 --- a/Data/Attoparsec/ByteString/Char8.hs +++ b/Data/Attoparsec/ByteString/Char8.hs @@ -120,6 +120,8 @@ module Data.Attoparsec.ByteString.Char8 , sepBy1' , skipMany , skipMany1 + , skipTill + , skipTill' , eitherP , I.match -- * State observation and manipulation functions diff --git a/Data/Attoparsec/Combinator.hs b/Data/Attoparsec/Combinator.hs index a90dccd9..84eec0d3 100644 --- a/Data/Attoparsec/Combinator.hs +++ b/Data/Attoparsec/Combinator.hs @@ -31,6 +31,8 @@ module Data.Attoparsec.Combinator , sepBy1' , skipMany , skipMany1 + , skipTill + , skipTill' , eitherP , feed , satisfyElem @@ -229,6 +231,34 @@ skipMany1 p = p *> skipMany p {-# SPECIALIZE skipMany1 :: Parser Text a -> Parser Text () #-} {-# SPECIALIZE skipMany1 :: Z.Parser a -> Z.Parser () #-} +-- | @skipTill p end@ applies action @p@ /zero/ or more times until +-- action @end@ succeeds, and returns the value returned by @end@. +-- This complements @manyTill@ and can be used to find a specific +-- pattern in a text. +-- +-- The value returned by @p@ is forced to WHNF. +skipTill :: Alternative f => f a -> f b -> f b +skipTill p end = scan + where scan = end <|> (p *> scan) +{-# SPECIALIZE skipTill :: Parser ByteString a -> Parser ByteString b + -> Parser ByteString b #-} +{-# SPECIALIZE skipTill :: Parser Text a -> Parser Text b -> Parser Text b #-} +{-# SPECIALIZE skipTill :: Z.Parser a -> Z.Parser b -> Z.Parser b #-} + +-- | @skipTill' p end@ applies action @p@ /zero/ or more times until +-- action @end@ succeeds, and returns the value returned by @end@. +-- This complements @manyTill'@ and can be used to find a specific +-- pattern in a text. +-- +-- The value returned by @p@ is forced to WHNF. +skipTill' :: (MonadPlus m) => m a -> m b -> m b +skipTill' p end = scan + where scan = end `mplus` (p *> scan) +{-# SPECIALIZE skipTill' :: Parser ByteString a -> Parser ByteString b + -> Parser ByteString b #-} +{-# SPECIALIZE skipTill' :: Parser Text a -> Parser Text b -> Parser Text b #-} +{-# SPECIALIZE skipTill' :: Z.Parser a -> Z.Parser b -> Z.Parser b #-} + -- | Apply the given action repeatedly, returning every result. count :: Monad m => Int -> m a -> m [a] count n p = sequence (replicate n p) diff --git a/Data/Attoparsec/Text.hs b/Data/Attoparsec/Text.hs index d93bdeb7..0deceda7 100644 --- a/Data/Attoparsec/Text.hs +++ b/Data/Attoparsec/Text.hs @@ -119,6 +119,8 @@ module Data.Attoparsec.Text , sepBy1' , skipMany , skipMany1 + , skipTill + , skipTill' , eitherP , I.match -- * State observation and manipulation functions From 169b3384b1f68171fd27cd1e440115e1bb79eb6b Mon Sep 17 00:00:00 2001 From: Shou Date: Wed, 30 Mar 2016 13:35:11 +0100 Subject: [PATCH 2/6] new function: till' --- Data/Attoparsec/Combinator.hs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Data/Attoparsec/Combinator.hs b/Data/Attoparsec/Combinator.hs index 84eec0d3..e3d57460 100644 --- a/Data/Attoparsec/Combinator.hs +++ b/Data/Attoparsec/Combinator.hs @@ -25,6 +25,7 @@ module Data.Attoparsec.Combinator , many1' , manyTill , manyTill' + , till' , sepBy , sepBy' , sepBy1 @@ -216,6 +217,20 @@ manyTill' p end = scan {-# SPECIALIZE manyTill' :: Parser Text a -> Parser Text b -> Parser Text [a] #-} {-# SPECIALIZE manyTill' :: Z.Parser a -> Z.Parser b -> Z.Parser [a] #-} +-- | @till' p end@ applies action @p@ /zero/ or more times until +-- action @end@ succeeds, and returns a tuple of the list of +-- values returned by @p@, and @end@. +-- +-- The value returned by @p@ is forced to WHNF. +till' :: (MonadPlus m) => m a -> m b -> m ([a], b) +till' p end = mapFst ($ []) <$> scan (id, undefined) + where scan (fp, e) = liftM (fp,) end `mplus` do !a <- p; scan (fp . (a:), e) + mapFst f (x, y) = (f x, y) +{-# SPECIALIZE till' :: Parser ByteString a -> Parser ByteString b + -> Parser ByteString ([a], b) #-} +{-# SPECIALIZE till' :: Parser Text a -> Parser Text b -> Parser Text ([a], b) #-} +{-# SPECIALIZE till' :: Z.Parser a -> Z.Parser b -> Z.Parser ([a], b) #-} + -- | Skip zero or more instances of an action. skipMany :: Alternative f => f a -> f () skipMany p = scan From deee7072f40a4f8b2c9c9cba4bbb62afa0b38e35 Mon Sep 17 00:00:00 2001 From: Shou Date: Wed, 30 Mar 2016 16:45:11 +0100 Subject: [PATCH 3/6] final --- Data/Attoparsec/Combinator.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Data/Attoparsec/Combinator.hs b/Data/Attoparsec/Combinator.hs index e3d57460..1d73ff88 100644 --- a/Data/Attoparsec/Combinator.hs +++ b/Data/Attoparsec/Combinator.hs @@ -1,4 +1,4 @@ -{-# LANGUAGE BangPatterns, CPP #-} +{-# LANGUAGE BangPatterns, CPP, TupleSections #-} #if __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Trustworthy #-} -- Imports internal modules #endif @@ -224,7 +224,7 @@ manyTill' p end = scan -- The value returned by @p@ is forced to WHNF. till' :: (MonadPlus m) => m a -> m b -> m ([a], b) till' p end = mapFst ($ []) <$> scan (id, undefined) - where scan (fp, e) = liftM (fp,) end `mplus` do !a <- p; scan (fp . (a:), e) + where scan (fp, e) = fmap (fp,) end `mplus` do !a <- p; scan (fp . (a:), e) mapFst f (x, y) = (f x, y) {-# SPECIALIZE till' :: Parser ByteString a -> Parser ByteString b -> Parser ByteString ([a], b) #-} From 90ec28fc1cc770d9bb476f07c4d3db08aa07254c Mon Sep 17 00:00:00 2001 From: Shou Date: Wed, 30 Mar 2016 17:09:36 +0100 Subject: [PATCH 4/6] exports --- Data/Attoparsec/ByteString.hs | 1 + Data/Attoparsec/ByteString/Char8.hs | 1 + Data/Attoparsec/Text.hs | 1 + 3 files changed, 3 insertions(+) diff --git a/Data/Attoparsec/ByteString.hs b/Data/Attoparsec/ByteString.hs index bcd0e438..3a0c83c0 100644 --- a/Data/Attoparsec/ByteString.hs +++ b/Data/Attoparsec/ByteString.hs @@ -83,6 +83,7 @@ module Data.Attoparsec.ByteString , many1' , manyTill , manyTill' + , till' , sepBy , sepBy' , sepBy1 diff --git a/Data/Attoparsec/ByteString/Char8.hs b/Data/Attoparsec/ByteString/Char8.hs index a9a9cd7f..b3aae097 100644 --- a/Data/Attoparsec/ByteString/Char8.hs +++ b/Data/Attoparsec/ByteString/Char8.hs @@ -114,6 +114,7 @@ module Data.Attoparsec.ByteString.Char8 , many1' , manyTill , manyTill' + , till' , sepBy , sepBy' , sepBy1 diff --git a/Data/Attoparsec/Text.hs b/Data/Attoparsec/Text.hs index 0deceda7..2e06b66c 100644 --- a/Data/Attoparsec/Text.hs +++ b/Data/Attoparsec/Text.hs @@ -113,6 +113,7 @@ module Data.Attoparsec.Text , many1' , manyTill , manyTill' + , till' , sepBy , sepBy' , sepBy1 From 90effdfb1f0a8556255fed0ce6ca5fe7cdcc39db Mon Sep 17 00:00:00 2001 From: Shou Date: Sat, 23 Apr 2016 06:53:45 +0100 Subject: [PATCH 5/6] WHNF on skipTill' p --- Data/Attoparsec/Combinator.hs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Data/Attoparsec/Combinator.hs b/Data/Attoparsec/Combinator.hs index 1d73ff88..6344714f 100644 --- a/Data/Attoparsec/Combinator.hs +++ b/Data/Attoparsec/Combinator.hs @@ -250,8 +250,6 @@ skipMany1 p = p *> skipMany p -- action @end@ succeeds, and returns the value returned by @end@. -- This complements @manyTill@ and can be used to find a specific -- pattern in a text. --- --- The value returned by @p@ is forced to WHNF. skipTill :: Alternative f => f a -> f b -> f b skipTill p end = scan where scan = end <|> (p *> scan) @@ -268,7 +266,8 @@ skipTill p end = scan -- The value returned by @p@ is forced to WHNF. skipTill' :: (MonadPlus m) => m a -> m b -> m b skipTill' p end = scan - where scan = end `mplus` (p *> scan) + where scan = end `mplus` (p !*> scan) + (!*>) !a0 a1 = a0 *> a1 {-# SPECIALIZE skipTill' :: Parser ByteString a -> Parser ByteString b -> Parser ByteString b #-} {-# SPECIALIZE skipTill' :: Parser Text a -> Parser Text b -> Parser Text b #-} From 073a4095bef55dbd93bd7aa6551c91967056bb44 Mon Sep 17 00:00:00 2001 From: Shou Date: Fri, 1 Jul 2016 06:21:38 +0100 Subject: [PATCH 6/6] skipTill': WHNF a, not m a --- Data/Attoparsec/Combinator.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Data/Attoparsec/Combinator.hs b/Data/Attoparsec/Combinator.hs index 6344714f..361eb80d 100644 --- a/Data/Attoparsec/Combinator.hs +++ b/Data/Attoparsec/Combinator.hs @@ -267,7 +267,7 @@ skipTill p end = scan skipTill' :: (MonadPlus m) => m a -> m b -> m b skipTill' p end = scan where scan = end `mplus` (p !*> scan) - (!*>) !a0 a1 = a0 *> a1 + (!*>) a0 a1 = fmap (\(!a) -> a) a0 *> a1 {-# SPECIALIZE skipTill' :: Parser ByteString a -> Parser ByteString b -> Parser ByteString b #-} {-# SPECIALIZE skipTill' :: Parser Text a -> Parser Text b -> Parser Text b #-}