attoparsec 0.8.5.0 → 0.8.5.1
raw patch · 5 files changed
+80/−31 lines, 5 filesdep +deepseqPVP: minor bump suggested
API additions: PVP suggests at least a minor version bump
Dependencies added: deepseq
API changes (from Hackage documentation)
+ Data.Attoparsec.Number: instance NFData Number
Files
- Data/Attoparsec.hs +1/−1
- Data/Attoparsec/Char8.hs +40/−15
- Data/Attoparsec/Internal.hs +30/−14
- Data/Attoparsec/Number.hs +6/−0
- attoparsec.cabal +3/−1
Data/Attoparsec.hs view
@@ -100,7 +100,7 @@ -- monad transformer. -- -- * Attoparsec is specialised to deal only with strict 'B.ByteString'--- input. Efficiency concernts rule out both lists and lazy+-- input. Efficiency concerns rule out both lists and lazy -- bytestrings. The usual use for lazy bytestrings would be to -- allow consumption of very large input without a large footprint. -- For this need, Attoparsec's incremental input provides an
Data/Attoparsec/Char8.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE BangPatterns, FlexibleInstances #-} {-# OPTIONS_GHC -fno-warn-orphans #-} -- |@@ -99,9 +99,10 @@ import Data.Attoparsec.Number (Number(..)) import Data.Bits (Bits, (.|.), shiftL) import Data.ByteString.Internal (c2w, w2c)+import Data.Int (Int8, Int16, Int32, Int64) import Data.Ratio ((%)) import Data.String (IsString(..))-import Data.Word (Word8)+import Data.Word (Word8, Word16, Word32, Word64, Word) import Prelude hiding (takeWhile) import qualified Data.Attoparsec as A import qualified Data.Attoparsec.Internal as I@@ -337,7 +338,6 @@ -- -- This parser does not accept a leading @\"0x\"@ string. hexadecimal :: (Integral a, Bits a) => Parser a-{-# SPECIALISE hexadecimal :: Parser Int #-} hexadecimal = B8.foldl' step 0 `fmap` I.takeWhile1 isHexDigit where isHexDigit w = (w >= 48 && w <= 57) ||@@ -346,25 +346,48 @@ step a w | w >= 48 && w <= 57 = (a `shiftL` 4) .|. fromIntegral (w - 48) | w >= 97 = (a `shiftL` 4) .|. fromIntegral (w - 87) | otherwise = (a `shiftL` 4) .|. fromIntegral (w - 55)+{-# SPECIALISE hexadecimal :: Parser Int #-}+{-# SPECIALISE hexadecimal :: Parser Int8 #-}+{-# SPECIALISE hexadecimal :: Parser Int16 #-}+{-# SPECIALISE hexadecimal :: Parser Int32 #-}+{-# SPECIALISE hexadecimal :: Parser Int64 #-}+{-# SPECIALISE hexadecimal :: Parser Integer #-}+{-# SPECIALISE hexadecimal :: Parser Word #-}+{-# SPECIALISE hexadecimal :: Parser Word8 #-}+{-# SPECIALISE hexadecimal :: Parser Word16 #-}+{-# SPECIALISE hexadecimal :: Parser Word32 #-}+{-# SPECIALISE hexadecimal :: Parser Word64 #-} -- | Parse and decode an unsigned decimal number. decimal :: Integral a => Parser a-{-# SPECIALISE decimal :: Parser Int #-}-{-# SPECIALISE decimal :: Parser Integer #-} decimal = B8.foldl' step 0 `fmap` I.takeWhile1 isDig where isDig w = w >= 48 && w <= 57 step a w = a * 10 + fromIntegral (w - 48)+{-# SPECIALISE decimal :: Parser Int #-}+{-# SPECIALISE decimal :: Parser Int8 #-}+{-# SPECIALISE decimal :: Parser Int16 #-}+{-# SPECIALISE decimal :: Parser Int32 #-}+{-# SPECIALISE decimal :: Parser Int64 #-}+{-# SPECIALISE decimal :: Parser Integer #-}+{-# SPECIALISE decimal :: Parser Word #-}+{-# SPECIALISE decimal :: Parser Word8 #-}+{-# SPECIALISE decimal :: Parser Word16 #-}+{-# SPECIALISE decimal :: Parser Word32 #-}+{-# SPECIALISE decimal :: Parser Word64 #-} -- | Parse a number with an optional leading @\'+\'@ or @\'-\'@ sign -- character. signed :: Num a => Parser a -> Parser a {-# SPECIALISE signed :: Parser Int -> Parser Int #-}+{-# SPECIALISE signed :: Parser Int8 -> Parser Int8 #-}+{-# SPECIALISE signed :: Parser Int16 -> Parser Int16 #-}+{-# SPECIALISE signed :: Parser Int32 -> Parser Int32 #-}+{-# SPECIALISE signed :: Parser Int64 -> Parser Int64 #-}+{-# SPECIALISE signed :: Parser Integer -> Parser Integer #-} signed p = (negate <$> (char8 '-' *> p)) <|> (char8 '+' *> p) <|> p -data T = T !Integer !Int- -- | Parse a rational number. -- -- This parser accepts an optional leading sign character, followed by@@ -391,6 +414,8 @@ -- >rational "3e" == Done 3.0 "e" rational :: Fractional a => Parser a {-# SPECIALIZE rational :: Parser Double #-}+{-# SPECIALIZE rational :: Parser Float #-}+{-# SPECIALIZE rational :: Parser Rational #-} rational = floaty $ \real frac fracDenom -> fromRational $ real % 1 + frac % fracDenom @@ -429,22 +454,23 @@ else D (asDouble real frac fracDenom) {-# INLINE number #-} +data T = T !Integer !Int+ floaty :: Fractional a => (Integer -> Integer -> Integer -> a) -> Parser a {-# INLINE floaty #-} floaty f = do let minus = 45 plus = 43- sign <- I.satisfy (\c -> c == minus || c == plus) <|> return plus+ !positive <- ((== plus) <$> I.satisfy (\c -> c == minus || c == plus)) <|>+ return True real <- decimal let tryFraction = do let dot = 46 _ <- I.satisfy (==dot) ds <- I.takeWhile isDigit_w8- case (case I.parse decimal ds of- I.Partial k -> k B.empty- r -> r) of- I.Done _ n -> return $ T n (B.length ds)- _ -> fail "no digits after decimal"+ case I.parseOnly decimal ds of+ Right n -> return $ T n (B.length ds)+ _ -> fail "no digits after decimal" T fraction fracDigits <- tryFraction <|> return (T 0 0) let littleE = 101 bigE = 69@@ -457,7 +483,6 @@ else if power == 0 then f real fraction (10 ^ fracDigits) else f real fraction (10 ^ fracDigits) * (10 ^^ power)- return $ if sign == plus+ return $ if positive then n else -n-
Data/Attoparsec/Internal.hs view
@@ -65,14 +65,15 @@ ) where import Control.Applicative (Alternative(..), Applicative(..), (<$>))+import Control.DeepSeq (NFData(rnf)) import Control.Monad (MonadPlus(..), when) import Data.Attoparsec.Combinator import Data.Attoparsec.FastSet (charClass, memberWord8) import Data.Monoid (Monoid(..)) import Data.Word (Word8) import Foreign.ForeignPtr (withForeignPtr)-import Foreign.Ptr (castPtr, plusPtr)-import Foreign.Storable (Storable(peek, sizeOf), peekByteOff)+import Foreign.Ptr (castPtr, minusPtr, plusPtr)+import Foreign.Storable (Storable(peek, sizeOf)) import Prelude hiding (getChar, take, takeWhile) import System.IO.Unsafe (unsafePerformIO) import qualified Data.ByteString as B8@@ -103,6 +104,12 @@ show (Partial _) = "Partial _" show (Done bs r) = "Done " ++ show bs ++ " " ++ show r +instance (NFData r) => NFData (Result r) where+ rnf (Fail _ _ _) = ()+ rnf (Partial _) = ()+ rnf (Done _ r) = rnf r+ {-# INLINE rnf #-}+ fmapR :: (a -> b) -> Result a -> Result b fmapR _ (Fail st stk msg) = Fail st stk msg fmapR f (Partial k) = Partial (fmapR f . k)@@ -135,7 +142,7 @@ addS i0 a0 m0 _i1 a1 m1 f = let !i = I (unI i0 +++ unA a1) a = A (unA a0 +++ unA a1)- m = m0 <> m1+ !m = m0 <> m1 in f i a m where Complete <> _ = Complete@@ -330,7 +337,8 @@ takeWith :: Int -> (B.ByteString -> Bool) -> Parser B.ByteString takeWith n p = do s <- ensure n- let (h,t) = B.splitAt n s+ let h = B.unsafeTake n s+ t = B.unsafeDrop n s if p h then put t >> return h else failDesc "takeWith"@@ -432,6 +440,8 @@ takeLazyByteString :: Parser L.ByteString takeLazyByteString = L.fromChunks `fmap` takeRest +data T s = T {-# UNPACK #-} !Int s+ -- | A stateful scanner. The predicate consumes and transforms a -- state argument, and each transformed state is passed to successive -- invocations of the predicate on each byte of the input until one@@ -452,16 +462,22 @@ where go acc s1 = do let scanner (B.PS fp off len) =- withForeignPtr fp $ \ptr -> do- let inner !i !s | i == off+len = done (i-off) s- | otherwise = do- w <- peekByteOff ptr i- case p s w of- Just s' -> inner (i+1) s'- Nothing -> done (i-off) s- done !i !s = return (B.PS fp off i, B.PS fp (off+i) (len-i),s)- inner off s1- (h,t,s') <- (unsafePerformIO . scanner) <$> get+ withForeignPtr fp $ \ptr0 -> do+ let start = ptr0 `plusPtr` off+ end = start `plusPtr` len+ inner ptr !s+ | ptr < end = do+ w <- peek ptr+ case p s w of+ Just s' -> inner (ptr `plusPtr` 1) s'+ _ -> done (ptr `minusPtr` start) s+ | otherwise = done (ptr `minusPtr` start) s+ done !i !s = return (T i s)+ inner start s1+ bs <- get+ let T i s' = unsafePerformIO $ scanner bs+ h = B.unsafeTake i bs+ t = B.unsafeDrop i bs put t if B.null t then do
Data/Attoparsec/Number.hs view
@@ -15,6 +15,7 @@ Number(..) ) where +import Control.DeepSeq (NFData(rnf)) import Data.Data (Data) import Data.Function (on) import Data.Typeable (Typeable)@@ -28,6 +29,11 @@ instance Show Number where show (I a) = show a show (D a) = show a++instance NFData Number where+ rnf (I _) = ()+ rnf (D _) = ()+ {-# INLINE rnf #-} binop :: (Integer -> Integer -> a) -> (Double -> Double -> a) -> Number -> Number -> a
attoparsec.cabal view
@@ -1,5 +1,5 @@ name: attoparsec-version: 0.8.5.0+version: 0.8.5.1 license: BSD3 license-file: LICENSE category: Text, Parsing@@ -51,6 +51,8 @@ cpp-options: -DAPPLICATIVE_IN_BASE else build-depends: base < 2.0++ build-depends: deepseq extensions: CPP exposed-modules: Data.Attoparsec