packages feed

attoparsec 0.12.0.0 → 0.12.1.0

raw patch · 8 files changed

+197/−117 lines, 8 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ Data.Attoparsec.Combinator: atEnd :: Chunk t => Parser t Bool
+ Data.Attoparsec.Combinator: endOfInput :: Chunk t => Parser t ()
+ Data.Attoparsec.Combinator: satisfyElem :: Chunk t => (ChunkElem t -> Bool) -> Parser t (ChunkElem t)
+ Data.Attoparsec.Types: chunkElemToChar :: Chunk c => c -> ChunkElem c -> Char
+ Data.Attoparsec.Types: class Monoid c => Chunk c
- Data.Attoparsec.ByteString: atEnd :: Parser Bool
+ Data.Attoparsec.ByteString: atEnd :: Chunk t => Parser t Bool
- Data.Attoparsec.ByteString: endOfInput :: Parser ()
+ Data.Attoparsec.ByteString: endOfInput :: Chunk t => Parser t ()
- Data.Attoparsec.ByteString.Char8: atEnd :: Parser Bool
+ Data.Attoparsec.ByteString.Char8: atEnd :: Chunk t => Parser t Bool
- Data.Attoparsec.ByteString.Char8: endOfInput :: Parser ()
+ Data.Attoparsec.ByteString.Char8: endOfInput :: Chunk t => Parser t ()
- Data.Attoparsec.Text: atEnd :: Parser Bool
+ Data.Attoparsec.Text: atEnd :: Chunk t => Parser t Bool
- Data.Attoparsec.Text: endOfInput :: Parser ()
+ Data.Attoparsec.Text: endOfInput :: Chunk t => Parser t ()

Files

Data/Attoparsec/ByteString/Internal.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE BangPatterns, OverloadedStrings, RecordWildCards #-}+{-# LANGUAGE BangPatterns, GADTs, OverloadedStrings, RecordWildCards #-} -- | -- Module      :  Data.Attoparsec.ByteString.Internal -- Copyright   :  Bryan O'Sullivan 2007-2014@@ -70,6 +70,7 @@ import Data.Attoparsec.ByteString.Buffer (Buffer, buffer) import Data.Attoparsec.ByteString.FastSet (charClass, memberWord8) import Data.Attoparsec.Combinator ((<?>))+import Data.Attoparsec.Internal import Data.Attoparsec.Internal.Fhthagn (inlinePerformIO) import Data.Attoparsec.Internal.Types hiding (Parser, Failure, Success) import Data.ByteString (ByteString)@@ -467,51 +468,6 @@ -- Non-recursive so the bounds check can be inlined: {-# INLINE ensure #-} --- | Ask for input.  If we receive any, pass it to a success--- continuation, otherwise to a failure continuation.-prompt :: Buffer -> Pos -> More-       -> (Buffer -> Pos -> More -> IResult ByteString r)-       -> (Buffer -> Pos -> More -> IResult ByteString r)-       -> IResult ByteString r-prompt t pos _more lose succ = Partial $ \s ->-  if B.null s-  then lose t pos Complete-  else succ (Buf.pappend t s) pos Incomplete---- | Immediately demand more input via a 'Partial' continuation--- result.-demandInput :: Parser ()-demandInput = T.Parser $ \t pos more lose succ ->-  case more of-    Complete -> lose t pos more [] "not enough input"-    _ -> let lose' t' pos' more' = lose t' pos' more' [] "not enough input"-             succ' t' pos' more' = succ t' pos' more' ()-         in prompt t pos more lose' succ'---- | This parser always succeeds.  It returns 'True' if any input is--- available either immediately or on demand, and 'False' if the end--- of all input has been reached.-wantInput :: Parser Bool-wantInput = T.Parser $ \t pos more _lose succ ->-  case () of-    _ | lengthAtLeast pos 1 t -> succ t pos more True-      | more == Complete -> succ t pos more False-      | otherwise       -> let lose' t' pos' more' = succ t' pos' more' False-                               succ' t' pos' more' = succ t' pos' more' True-                           in prompt t pos more lose' succ'-{-# INLINE wantInput #-}---- | Match only if all input has been consumed.-endOfInput :: Parser ()-endOfInput = T.Parser $ \t pos more lose succ ->-  case () of-    _| lengthAtLeast pos 1 t -> lose t pos more [] "endOfInput"-     | more == Complete -> succ t pos more ()-     | otherwise ->-       let lose' t' pos' more' _ctx _msg = succ t' pos' more' ()-           succ' t' pos' more' _a = lose t' pos' more' [] "endOfInput"-       in  runParser demandInput t pos more lose' succ'- -- | Return both the result of a parse and the portion of the input -- that was consumed while it was being parsed. match :: Parser a -> Parser (ByteString, a)@@ -519,12 +475,6 @@   let succ' t' pos' more' a =         succ t' pos' more' (substring pos (pos'-pos) t', a)   in runParser p t pos more lose succ'---- | Return an indication of whether the end of input has been--- reached.-atEnd :: Parser Bool-atEnd = not <$> wantInput-{-# INLINE atEnd #-}  lengthAtLeast :: Pos -> Int -> Buffer -> Bool lengthAtLeast (Pos pos) n bs = Buf.length bs >= pos + n
Data/Attoparsec/Combinator.hs view
@@ -30,12 +30,16 @@     , skipMany1     , eitherP     , feed+    , satisfyElem+    , endOfInput+    , atEnd     ) where  import Control.Applicative (Alternative(..), Applicative(..), empty, liftA2,                             many, (<|>), (*>), (<$>)) import Control.Monad (MonadPlus(..)) import Data.Attoparsec.Internal.Types (Parser(..), IResult(..))+import Data.Attoparsec.Internal (endOfInput, atEnd, satisfyElem) import Data.ByteString (ByteString) import Data.Monoid (Monoid(mappend)) import Data.Text (Text)
Data/Attoparsec/Internal.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE CPP, BangPatterns, ScopedTypeVariables #-} -- | -- Module      :  Data.Attoparsec.Internal -- Copyright   :  Bryan O'Sullivan 2007-2014@@ -12,10 +12,20 @@ -- library.  module Data.Attoparsec.Internal-    (-      compareResults+    ( compareResults+    , prompt+    , demandInput+    , wantInput+    , endOfInput+    , atEnd+    , satisfyElem     ) where +import Control.Applicative ((<$>))+#if __GLASGOW_HASKELL__ >= 700+import Data.ByteString (ByteString)+import Data.Text (Text)+#endif import Data.Attoparsec.Internal.Types import Prelude hiding (succ) @@ -31,3 +41,115 @@     Just (t0 == t1 && r0 == r1) compareResults (Partial _) (Partial _) = Nothing compareResults _ _ = Just False++-- | Ask for input.  If we receive any, pass it to a success+-- continuation, otherwise to a failure continuation.+prompt :: Chunk t+       => State t -> Pos -> More+       -> (State t -> Pos -> More -> IResult t r)+       -> (State t -> Pos -> More -> IResult t r)+       -> IResult t r+prompt t pos _more lose succ = Partial $ \s ->+  if nullChunk s+  then lose t pos Complete+  else succ (pappendChunk t s) pos Incomplete+#if __GLASGOW_HASKELL__ >= 700+{-# SPECIALIZE prompt :: State ByteString -> Pos -> More+                      -> (State ByteString -> Pos -> More+                          -> IResult ByteString r)+                      -> (State ByteString -> Pos -> More+                          -> IResult ByteString r)+                      -> IResult ByteString r #-}+{-# SPECIALIZE prompt :: State Text -> Pos -> More+                      -> (State Text -> Pos -> More -> IResult Text r)+                      -> (State Text -> Pos -> More -> IResult Text r)+                      -> IResult Text r #-}+#endif++-- | Immediately demand more input via a 'Partial' continuation+-- result.+demandInput :: Chunk t => Parser t ()+demandInput = Parser $ \t pos more lose succ ->+  case more of+    Complete -> lose t pos more [] "not enough input"+    _ -> let lose' t' pos' more' = lose t' pos' more' [] "not enough input"+             succ' t' pos' more' = succ t' pos' more' ()+         in prompt t pos more lose' succ'+#if __GLASGOW_HASKELL__ >= 700+{-# SPECIALIZE demandInput :: Parser ByteString () #-}+{-# SPECIALIZE demandInput :: Parser Text () #-}+#endif++-- | This parser always succeeds.  It returns 'True' if any input is+-- available either immediately or on demand, and 'False' if the end+-- of all input has been reached.+wantInput :: forall t . Chunk t => Parser t Bool+wantInput = Parser $ \t pos more _lose succ ->+  case () of+    _ | pos < atBufferEnd (undefined :: t) t -> succ t pos more True+      | more == Complete -> succ t pos more False+      | otherwise       -> let lose' t' pos' more' = succ t' pos' more' False+                               succ' t' pos' more' = succ t' pos' more' True+                           in prompt t pos more lose' succ'+{-# INLINE wantInput #-}++-- | Match only if all input has been consumed.+endOfInput :: forall t . Chunk t => Parser t ()+endOfInput = Parser $ \t pos more lose succ ->+  case () of+    _| pos < atBufferEnd (undefined :: t) t -> lose t pos more [] "endOfInput"+     | more == Complete -> succ t pos more ()+     | otherwise ->+       let lose' t' pos' more' _ctx _msg = succ t' pos' more' ()+           succ' t' pos' more' _a = lose t' pos' more' [] "endOfInput"+       in  runParser demandInput t pos more lose' succ'+#if __GLASGOW_HASKELL__ >= 700+{-# SPECIALIZE endOfInput :: Parser ByteString () #-}+{-# SPECIALIZE endOfInput :: Parser Text () #-}+#endif++-- | Return an indication of whether the end of input has been+-- reached.+atEnd :: Chunk t => Parser t Bool+atEnd = not <$> wantInput+{-# INLINE atEnd #-}++satisfySuspended :: forall t r . Chunk t+                 => (ChunkElem t -> Bool)+                 -> State t -> Pos -> More+                 -> Failure t (State t) r+                 -> Success t (State t) (ChunkElem t) r+                 -> IResult t r+satisfySuspended p t pos more lose succ =+    runParser (demandInput >> go) t pos more lose succ+  where go = Parser $ \t' pos' more' lose' succ' ->+          case bufferElemAt (undefined :: t) pos' t' of+            Just (e, l) | p e -> succ' t' (pos' + Pos l) more' e+                        | otherwise -> lose' t' pos' more' [] "satisfyElem"+            Nothing -> runParser (demandInput >> go) t' pos' more' lose' succ'+#if __GLASGOW_HASKELL__ >= 700+{-# SPECIALIZE satisfySuspended :: (ChunkElem ByteString -> Bool)+                                -> State ByteString -> Pos -> More+                                -> Failure ByteString (State ByteString) r+                                -> Success ByteString (State ByteString)+                                           (ChunkElem ByteString) r+                                -> IResult ByteString r #-}+{-# SPECIALIZE satisfySuspended :: (ChunkElem Text -> Bool)+                                -> State Text -> Pos -> More+                                -> Failure Text (State Text) r+                                -> Success Text (State Text)+                                           (ChunkElem Text) r+                                -> IResult Text r #-}+#endif++-- | The parser @satisfyElem p@ succeeds for any chunk element for which the+-- predicate @p@ returns 'True'. Returns the element that is+-- actually parsed.+satisfyElem :: forall t . Chunk t+            => (ChunkElem t -> Bool) -> Parser t (ChunkElem t)+satisfyElem p = Parser $ \t pos more lose succ ->+    case bufferElemAt (undefined :: t) pos t of+      Just (e, l) | p e -> succ t (pos + Pos l) more e+                  | otherwise -> lose t pos more [] "satisfyElem"+      Nothing -> satisfySuspended p t pos more lose succ+{-# INLINE satisfyElem #-}
Data/Attoparsec/Internal/Types.hs view
@@ -15,21 +15,27 @@ module Data.Attoparsec.Internal.Types     (       Parser(..)-    , Input(..)+    , State     , Failure     , Success     , Pos(..)     , IResult(..)     , More(..)     , (<>)+    , Chunk(..)     ) where  import Control.Applicative (Alternative(..), Applicative(..), (<$>)) import Control.DeepSeq (NFData(rnf)) import Control.Monad (MonadPlus(..))+import Data.Word (Word8) import Data.ByteString (ByteString)+import qualified Data.ByteString as BS+import Data.ByteString.Internal (w2c) import Data.Monoid (Monoid(..)) import Data.Text (Text)+import qualified Data.Text as Text+import Data.Text.Unsafe (Iter(..)) import Prelude hiding (getChar, succ) import qualified Data.Attoparsec.ByteString.Buffer as B import qualified Data.Attoparsec.Text.Buffer as T@@ -96,21 +102,16 @@ -- -- * 'Alternative', which follows 'MonadPlus'. newtype Parser i a = Parser {-      runParser :: forall r. Input i =>+      runParser :: forall r.                    State i -> Pos -> More                 -> Failure i (State i)   r                 -> Success i (State i) a r                 -> IResult i r     } -class Input i where-    type State i :: *--instance Input ByteString where-    type State ByteString = B.Buffer--instance Input Text where-    type State Text = T.Buffer+type family State i+type instance State ByteString = B.Buffer+type instance State Text = T.Buffer  type Failure i t   r = t -> Pos -> More -> [String] -> String                        -> IResult i r@@ -202,3 +203,48 @@ (<>) :: (Monoid m) => m -> m -> m (<>) = mappend {-# INLINE (<>) #-}++-- | A common interface for input chunks.+class Monoid c => Chunk c where+  type ChunkElem c+  -- | Test if the chunk is empty.+  nullChunk :: c -> Bool+  -- | Append chunk to a buffer.+  pappendChunk :: State c -> c -> State c+  -- | Position at the end of a buffer. The first argument is ignored.+  atBufferEnd :: c -> State c -> Pos+  -- | Return the buffer element at the given position along with its length.+  bufferElemAt :: c -> Pos -> State c -> Maybe (ChunkElem c, Int)+  -- | Map an element to the corresponding character.+  --   The first argument is ignored.+  chunkElemToChar :: c -> ChunkElem c -> Char++instance Chunk ByteString where+  type ChunkElem ByteString = Word8+  nullChunk = BS.null+  {-# INLINE nullChunk #-}+  pappendChunk = B.pappend+  {-# INLINE pappendChunk #-}+  atBufferEnd _ = Pos . B.length+  {-# INLINE atBufferEnd #-}+  bufferElemAt _ (Pos i) buf+    | i < B.length buf = Just (B.unsafeIndex buf i, 1)+    | otherwise = Nothing+  {-# INLINE bufferElemAt #-}+  chunkElemToChar _ = w2c+  {-# INLINE chunkElemToChar #-}++instance Chunk Text where+  type ChunkElem Text = Char+  nullChunk = Text.null+  {-# INLINE nullChunk #-}+  pappendChunk = T.pappend+  {-# INLINE pappendChunk #-}+  atBufferEnd _ = Pos . T.length+  {-# INLINE atBufferEnd #-}+  bufferElemAt _ (Pos i) buf+    | i < T.length buf = let Iter c l = T.iter buf i in Just (c, l)+    | otherwise = Nothing+  {-# INLINE bufferElemAt #-}+  chunkElemToChar _ = id+  {-# INLINE chunkElemToChar #-}
Data/Attoparsec/Text/Internal.hs view
@@ -68,6 +68,7 @@ import Control.Applicative ((<|>), (<$>)) import Control.Monad (when) import Data.Attoparsec.Combinator ((<?>))+import Data.Attoparsec.Internal import Data.Attoparsec.Internal.Types hiding (Parser, Failure, Success) import qualified Data.Attoparsec.Text.Buffer as Buf import Data.Attoparsec.Text.Buffer (Buffer, buffer)@@ -478,50 +479,6 @@ -- Non-recursive so the bounds check can be inlined: {-# INLINE ensure #-} --- | Ask for input.  If we receive any, pass it to a success--- continuation, otherwise to a failure continuation.-prompt :: Buffer -> Pos -> More-       -> (Buffer -> Pos -> More -> IResult Text r)-       -> (Buffer -> Pos -> More -> IResult Text r)-       -> IResult Text r-prompt t pos _more lose succ = Partial $ \s ->-  if T.null s-  then lose t pos Complete-  else succ (Buf.pappend t s) pos Incomplete---- | Immediately demand more input via a 'Partial' continuation--- result.-demandInput :: Parser ()-demandInput = T.Parser $ \t pos more lose succ ->-  case more of-    Complete -> lose t pos more [] "not enough input"-    _ -> let lose' t' pos' more' = lose t' pos' more' [] "not enough input"-             succ' t' pos' more' = succ t' pos' more' ()-         in prompt t pos more lose' succ'---- | This parser always succeeds.  It returns 'True' if any input is--- available either immediately or on demand, and 'False' if the end--- of all input has been reached.-wantInput :: Parser Bool-wantInput = T.Parser $ \t pos more _lose succ ->-  case () of-    _ | pos < lengthOf t -> succ t pos more True-      | more == Complete -> succ t pos more False-      | otherwise       -> let lose' t' pos' more' = succ t' pos' more' False-                               succ' t' pos' more' = succ t' pos' more' True-                           in prompt t pos more lose' succ'---- | Match only if all input has been consumed.-endOfInput :: Parser ()-endOfInput = T.Parser $ \t pos more lose succ ->-  case () of-    _| pos < lengthOf t -> lose t pos more [] "endOfInput"-     | more == Complete -> succ t pos more ()-     | otherwise ->-       let lose' t' pos' more' _ctx _msg = succ t' pos' more' ()-           succ' t' pos' more' _a = lose t' pos' more' [] "endOfInput"-       in  runParser demandInput t pos more lose' succ'- -- | Return both the result of a parse and the portion of the input -- that was consumed while it was being parsed. match :: Parser a -> Parser (Text, a)@@ -529,12 +486,6 @@   let succ' t' pos' more' a = succ t' pos' more'                               (substring pos (pos'-pos) t', a)   in runParser p t pos more lose succ'---- | Return an indication of whether the end of input has been--- reached.-atEnd :: Parser Bool-atEnd = not <$> wantInput-{-# INLINE atEnd #-}  lengthAtLeast :: Pos -> Int -> Buffer -> Maybe Pos lengthAtLeast pos n t = go 0 (fromPos pos)
Data/Attoparsec/Types.hs view
@@ -14,6 +14,7 @@     (       Parser     , IResult(..)+    , Chunk(chunkElemToChar)     ) where -import Data.Attoparsec.Internal.Types (Parser(..), IResult(..))+import Data.Attoparsec.Internal.Types (Parser(..), IResult(..), Chunk(..))
attoparsec.cabal view
@@ -1,5 +1,5 @@ name:            attoparsec-version:         0.12.0.0+version:         0.12.1.0 license:         BSD3 license-file:    LICENSE category:        Text, Parsing
changelog.md view
@@ -1,3 +1,9 @@+0.12.1.0++* Now compatible with GHC 7.9++* Reintroduced the Chunk class, used by the parsers package+ 0.12.0.0  * A new internal representation makes almost all real-world parsers