aboutsummaryrefslogtreecommitdiff
path: root/haddock-library/vendor/attoparsec-0.10.4.0/Data/Attoparsec/Combinator.hs
diff options
context:
space:
mode:
authorMateusz Kowalczyk <fuuzetsu@fuuzetsu.co.uk>2014-05-05 09:01:03 +0200
committerMateusz Kowalczyk <fuuzetsu@fuuzetsu.co.uk>2014-05-05 11:00:41 +0200
commitcc269e6b0b615e9e237c35a985e4ace7b9ab0dd9 (patch)
treef0264138c81909151f9724c1f02f7bf8b30803cb /haddock-library/vendor/attoparsec-0.10.4.0/Data/Attoparsec/Combinator.hs
parent7ac2d0f2d31c2e1c7ede09828f3d5ba5626bd0d4 (diff)
Move parser + parser tests out to own package.
We move some types out that are necessary as well and then re-export and specialise them in the core Haddock. Reason for moving out spec tests is that if we're working on the parser, we can simply work on that and we can ignore the rest of Haddock. The downside is that it's a little inconvenient if at the end of the day we want to see that everything passes.
Diffstat (limited to 'haddock-library/vendor/attoparsec-0.10.4.0/Data/Attoparsec/Combinator.hs')
-rw-r--r--haddock-library/vendor/attoparsec-0.10.4.0/Data/Attoparsec/Combinator.hs205
1 files changed, 205 insertions, 0 deletions
diff --git a/haddock-library/vendor/attoparsec-0.10.4.0/Data/Attoparsec/Combinator.hs b/haddock-library/vendor/attoparsec-0.10.4.0/Data/Attoparsec/Combinator.hs
new file mode 100644
index 00000000..cb9cee83
--- /dev/null
+++ b/haddock-library/vendor/attoparsec-0.10.4.0/Data/Attoparsec/Combinator.hs
@@ -0,0 +1,205 @@
+{-# LANGUAGE BangPatterns, CPP #-}
+-- |
+-- Module : Data.Attoparsec.Combinator
+-- Copyright : Daan Leijen 1999-2001, Bryan O'Sullivan 2009-2010
+-- License : BSD3
+--
+-- Maintainer : bos@serpentine.com
+-- Stability : experimental
+-- Portability : portable
+--
+-- Useful parser combinators, similar to those provided by Parsec.
+module Data.Attoparsec.Combinator
+ (
+ choice
+ , count
+ , option
+ , many'
+ , many1
+ , many1'
+ , manyTill
+ , manyTill'
+ , sepBy
+ , sepBy'
+ , sepBy1
+ , sepBy1'
+ , skipMany
+ , skipMany1
+ , eitherP
+ ) where
+
+import Control.Applicative (Alternative(..), Applicative(..), empty, liftA2,
+ (<|>), (*>), (<$>))
+import Control.Monad (MonadPlus(..))
+#if !MIN_VERSION_base(4,2,0)
+import Control.Applicative (many)
+#endif
+
+#if __GLASGOW_HASKELL__ >= 700
+import Data.Attoparsec.Internal.Types (Parser)
+import Data.ByteString (ByteString)
+#endif
+
+-- | @choice ps@ tries to apply the actions in the list @ps@ in order,
+-- until one of them succeeds. Returns the value of the succeeding
+-- action.
+choice :: Alternative f => [f a] -> f a
+choice = foldr (<|>) empty
+#if __GLASGOW_HASKELL__ >= 700
+{-# SPECIALIZE choice :: [Parser ByteString a] -> Parser ByteString a #-}
+#endif
+
+-- | @option x p@ tries to apply action @p@. If @p@ fails without
+-- consuming input, it returns the value @x@, otherwise the value
+-- returned by @p@.
+--
+-- > priority = option 0 (digitToInt <$> digit)
+option :: Alternative f => a -> f a -> f a
+option x p = p <|> pure x
+#if __GLASGOW_HASKELL__ >= 700
+{-# SPECIALIZE option :: a -> Parser ByteString a -> Parser ByteString a #-}
+#endif
+
+-- | A version of 'liftM2' that is strict in the result of its first
+-- action.
+liftM2' :: (Monad m) => (a -> b -> c) -> m a -> m b -> m c
+liftM2' f a b = do
+ !x <- a
+ y <- b
+ return (f x y)
+{-# INLINE liftM2' #-}
+
+-- | @many' p@ applies the action @p@ /zero/ or more times. Returns a
+-- list of the returned values of @p@. The value returned by @p@ is
+-- forced to WHNF.
+--
+-- > word = many' letter
+many' :: (MonadPlus m) => m a -> m [a]
+many' p = many_p
+ where many_p = some_p `mplus` return []
+ some_p = liftM2' (:) p many_p
+{-# INLINE many' #-}
+
+-- | @many1 p@ applies the action @p@ /one/ or more times. Returns a
+-- list of the returned values of @p@.
+--
+-- > word = many1 letter
+many1 :: Alternative f => f a -> f [a]
+many1 p = liftA2 (:) p (many p)
+{-# INLINE many1 #-}
+
+-- | @many1' p@ applies the action @p@ /one/ or more times. Returns a
+-- list of the returned values of @p@. The value returned by @p@ is
+-- forced to WHNF.
+--
+-- > word = many1' letter
+many1' :: (MonadPlus m) => m a -> m [a]
+many1' p = liftM2' (:) p (many' p)
+{-# INLINE many1' #-}
+
+-- | @sepBy p sep@ applies /zero/ or more occurrences of @p@, separated
+-- by @sep@. Returns a list of the values returned by @p@.
+--
+-- > commaSep p = p `sepBy` (symbol ",")
+sepBy :: Alternative f => f a -> f s -> f [a]
+sepBy p s = liftA2 (:) p ((s *> sepBy1 p s) <|> pure []) <|> pure []
+#if __GLASGOW_HASKELL__ >= 700
+{-# SPECIALIZE sepBy :: Parser ByteString a -> Parser ByteString s
+ -> Parser ByteString [a] #-}
+#endif
+
+-- | @sepBy' p sep@ applies /zero/ or more occurrences of @p@, separated
+-- by @sep@. Returns a list of the values returned by @p@. The value
+-- returned by @p@ is forced to WHNF.
+--
+-- > commaSep p = p `sepBy'` (symbol ",")
+sepBy' :: (MonadPlus m) => m a -> m s -> m [a]
+sepBy' p s = scan `mplus` return []
+ where scan = liftM2' (:) p ((s >> sepBy1' p s) `mplus` return [])
+#if __GLASGOW_HASKELL__ >= 700
+{-# SPECIALIZE sepBy' :: Parser ByteString a -> Parser ByteString s
+ -> Parser ByteString [a] #-}
+#endif
+
+-- | @sepBy1 p sep@ applies /one/ or more occurrences of @p@, separated
+-- by @sep@. Returns a list of the values returned by @p@.
+--
+-- > commaSep p = p `sepBy1` (symbol ",")
+sepBy1 :: Alternative f => f a -> f s -> f [a]
+sepBy1 p s = scan
+ where scan = liftA2 (:) p ((s *> scan) <|> pure [])
+#if __GLASGOW_HASKELL__ >= 700
+{-# SPECIALIZE sepBy1 :: Parser ByteString a -> Parser ByteString s
+ -> Parser ByteString [a] #-}
+#endif
+
+-- | @sepBy1' p sep@ applies /one/ or more occurrences of @p@, separated
+-- by @sep@. Returns a list of the values returned by @p@. The value
+-- returned by @p@ is forced to WHNF.
+--
+-- > commaSep p = p `sepBy1'` (symbol ",")
+sepBy1' :: (MonadPlus m) => m a -> m s -> m [a]
+sepBy1' p s = scan
+ where scan = liftM2' (:) p ((s >> scan) `mplus` return [])
+#if __GLASGOW_HASKELL__ >= 700
+{-# SPECIALIZE sepBy1' :: Parser ByteString a -> Parser ByteString s
+ -> Parser ByteString [a] #-}
+#endif
+
+-- | @manyTill p end@ applies action @p@ /zero/ or more times until
+-- action @end@ succeeds, and returns the list of values returned by
+-- @p@. This can be used to scan comments:
+--
+-- > simpleComment = string "<!--" *> manyTill anyChar (try (string "-->"))
+--
+-- Note the overlapping parsers @anyChar@ and @string \"<!--\"@, and
+-- therefore the use of the 'try' combinator.
+manyTill :: Alternative f => f a -> f b -> f [a]
+manyTill p end = scan
+ where scan = (end *> pure []) <|> liftA2 (:) p scan
+#if __GLASGOW_HASKELL__ >= 700
+{-# SPECIALIZE manyTill :: Parser ByteString a -> Parser ByteString b
+ -> Parser ByteString [a] #-}
+#endif
+
+-- | @manyTill' p end@ applies action @p@ /zero/ or more times until
+-- action @end@ succeeds, and returns the list of values returned by
+-- @p@. This can be used to scan comments:
+--
+-- > simpleComment = string "<!--" *> manyTill' anyChar (try (string "-->"))
+--
+-- Note the overlapping parsers @anyChar@ and @string \"<!--\"@, and
+-- therefore the use of the 'try' combinator. The value returned by @p@
+-- is forced to WHNF.
+manyTill' :: (MonadPlus m) => m a -> m b -> m [a]
+manyTill' p end = scan
+ where scan = (end >> return []) `mplus` liftM2' (:) p scan
+#if __GLASGOW_HASKELL__ >= 700
+{-# SPECIALIZE manyTill' :: Parser ByteString a -> Parser ByteString b
+ -> Parser ByteString [a] #-}
+#endif
+
+-- | Skip zero or more instances of an action.
+skipMany :: Alternative f => f a -> f ()
+skipMany p = scan
+ where scan = (p *> scan) <|> pure ()
+#if __GLASGOW_HASKELL__ >= 700
+{-# SPECIALIZE skipMany :: Parser ByteString a -> Parser ByteString () #-}
+#endif
+
+-- | Skip one or more instances of an action.
+skipMany1 :: Alternative f => f a -> f ()
+skipMany1 p = p *> skipMany p
+#if __GLASGOW_HASKELL__ >= 700
+{-# SPECIALIZE skipMany1 :: Parser ByteString a -> Parser ByteString () #-}
+#endif
+
+-- | Apply the given action repeatedly, returning every result.
+count :: Monad m => Int -> m a -> m [a]
+count n p = sequence (replicate n p)
+{-# INLINE count #-}
+
+-- | Combine two alternatives.
+eitherP :: (Alternative f) => f a -> f b -> f (Either a b)
+eitherP a b = (Left <$> a) <|> (Right <$> b)
+{-# INLINE eitherP #-}