packages feed

attoparsec-text 0.8.2.1 → 0.8.5.0

raw patch · 4 files changed

+287/−158 lines, 4 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Data.Attoparsec.Text: ensure :: Int -> Parser ()
- Data.Attoparsec.Text: instance Functor Result
- Data.Attoparsec.Text: instance Show r => Show (Result r)
+ Data.Attoparsec.Text: atEnd :: Parser Bool
+ Data.Attoparsec.Text: parseOnly :: Parser a -> Text -> Either String a
+ Data.Attoparsec.Text: scan :: s -> (s -> Char -> Maybe s) -> Parser Text
+ Data.Attoparsec.Text: takeLazyText :: Parser Text
+ Data.Attoparsec.Text: takeText :: Parser Text
- Data.Attoparsec.Text: Done :: !Text -> r -> Result r
+ Data.Attoparsec.Text: Done :: Text -> r -> Result r
- Data.Attoparsec.Text: Fail :: !Text -> [String] -> String -> Result r
+ Data.Attoparsec.Text: Fail :: Text -> [String] -> String -> Result r

Files

Data/Attoparsec/Text.hs view
@@ -15,6 +15,9 @@     -- * Differences from Parsec     -- $parsec +    -- * Incremental input+    -- $incremental+     -- * Performance considerations     -- $performance @@ -27,9 +30,10 @@      -- * Running parsers     , parse-    , parseTest-    , parseWith     , feed+    , I.parseOnly+    , parseWith+    , parseTest      -- ** Result conversion     , maybeResult@@ -63,10 +67,15 @@     , I.skipSpace     , I.skipWhile     , I.take+    , I.scan     , I.takeWhile     , I.takeWhile1     , I.takeTill +    -- ** Consume all remaining input+    , I.takeText+    , I.takeLazyText+     -- * Text parsing     , I.endOfLine @@ -79,7 +88,7 @@      -- * State observation and manipulation functions     , I.endOfInput-    , I.ensure+    , I.atEnd      -- * Applicative specializations     -- $applicative@@ -91,6 +100,7 @@ import Data.Attoparsec.Combinator import qualified Data.Attoparsec.Text.Internal as I import qualified Data.Text as T+import Data.Attoparsec.Text.Internal (Result(..), parse)  -- $parsec --@@ -107,12 +117,11 @@ -- * Much of the performance advantage of @attoparsec-text@ is --   gained via high-performance parsers such as 'I.takeWhile' --   and 'I.string'.  If you use complicated combinators that---   return lists of characters, there really isn't much---   performance difference the two libraries.+--   return lists of characters, there is less performance+--   difference between the two libraries. -- -- * Unlike Parsec 3, @attoparsec-text@ does not support being---   used as a monad transformer.  This is mostly a matter of the---   implementor not having needed that functionality.+--   used as a monad transformer. -- -- * @attoparsec-text@ is specialised to deal only with strict --   'T.Text' input.  Efficiency concernts rule out both lists@@ -120,13 +129,39 @@ --   allow consumption of very large input without a large --   footprint.  For this need, @attoparsec-text@'s incremental --   input provides an excellent substitute, with much more---   control over when input takes place.+--   control over when input takes place.  If you must use lazy+--   texts, see the 'Lazy' module, which feeds lazy chunks to a+--   regular parser. -- -- * Parsec parsers can produce more helpful error messages than --   @attoparsec-text@ parsers.  This is a matter of focus: --   @attoparsec-text@ avoids the extra book-keeping in favour of --   higher performance. +-- $incremental+--+-- @attoparsec-text@ supports incremental input, meaning that you+-- can feed it a text that represents only part of the+-- expected total amount of data to parse. If your parser reaches+-- the end of a fragment of input and could consume more input,+-- it will suspend parsing and return a 'Partial' continuation.+--+-- Supplying the 'Partial' continuation with another text will+-- resume parsing at the point where it was suspended. You must be+-- prepared for the result of the resumed parse to be another+-- 'Partial' continuation.+--+-- To indicate that you have no more input, supply the 'Partial'+-- continuation with an empty text.+--+-- Remember that some parsing combinators will not return a result+-- until they reach the end of input.  They may thus cause 'Partial'+-- results to be returned.+--+-- If you do not need support for incremental input, consider using+-- the 'I.parseOnly' function to run your parser.  It will never+-- prompt for more input.+ -- $performance -- -- To actually achieve high performance, there are a few guidelines@@ -166,57 +201,18 @@ -- The 'Result' type is an instance of 'Functor', where 'fmap' -- transforms the value in a 'Done' result. --- | The result of a parse.-data Result r = Fail !T.Text [String] String-              -- ^ The parse failed.  The 'T.Text' is the input-              -- that had not yet been consumed when the failure-              -- occurred.  The @[@'String'@]@ is a list of contexts-              -- in which the error occurred.  The 'String' is the-              -- message describing the error, if any.-              | Partial (T.Text -> Result r)-              -- ^ Supply this continuation with more input so that-              -- the parser can resume.  To indicate that no more-              -- input is available, use an 'T.empty' string.-              | Done !T.Text r-              -- ^ The parse succeeded.  The 'T.Text' is the-              -- input that had not yet been consumed (if any) when-              -- the parse succeeded.--instance Show r => Show (Result r) where-    show (Fail bs stk msg) =-        "Fail " ++ show bs ++ " " ++ show stk ++ " " ++ show msg-    show (Partial _)       = "Partial _"-    show (Done bs r)       = "Done " ++ show bs ++ " " ++ show r- -- | If a parser has returned a 'Partial' result, supply it with more -- input. feed :: Result r -> T.Text -> Result r feed f@(Fail _ _ _) _ = f feed (Partial k) d    = k d feed (Done bs r) d    = Done (T.append bs d) r--fmapR :: (a -> b) -> Result a -> Result b-fmapR _ (Fail st stk msg) = Fail st stk msg-fmapR f (Partial k)       = Partial (fmapR f . k)-fmapR f (Done bs r)       = Done bs (f r)--instance Functor Result where-    fmap = fmapR+{-# INLINE feed #-}  -- | Run a parser and print its result to standard output. parseTest :: (Show a) => I.Parser a -> T.Text -> IO () parseTest p s = print (parse p s) -translate :: I.Result a -> Result a-translate (I.Fail st stk msg) = Fail (I.input st) stk msg-translate (I.Partial k)       = Partial (translate . k)-translate (I.Done st r)       = Done (I.input st) r---- | Run a parser and return its result.-parse :: I.Parser a -> T.Text -> Result a-parse m s = translate (I.parse m s)-{-# INLINE parse #-}- -- | Run a parser with an initial input string, and a monadic action -- that can supply more input if needed. parseWith :: Monad m =>@@ -228,10 +224,9 @@           -> T.Text           -- ^ Initial input for the parser.           -> m (Result a)-parseWith refill p s = step $ I.parse p s-  where step (I.Fail st stk msg) = return $! Fail (I.input st) stk msg-        step (I.Partial k)       = (step . k) =<< refill-        step (I.Done st r)       = return $! Done (I.input st) r+parseWith refill p s = step $ parse p s+  where step (Partial k) = (step . k) =<< refill+        step r           = return r  -- | Convert a 'Result' value to a 'Maybe' value. A 'Partial' result -- is treated as failure.
Data/Attoparsec/Text/Internal.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE Rank2Types, RecordWildCards, FlexibleInstances #-}+{-# LANGUAGE BangPatterns, Rank2Types, RecordWildCards, FlexibleInstances #-} -- | -- Module      :  Data.Attoparsec.Text.Internal -- Copyright   :  Felipe Lessa 2010-2011, Bryan O'Sullivan 2007-2010@@ -16,10 +16,10 @@     -- * Parser types       Parser     , Result(..)-    , S(input)      -- * Running parsers     , parse+    , parseOnly      -- * Combinators     , (<?>)@@ -49,10 +49,15 @@     , string     , stringTransform     , take+    , scan     , takeWhile     , takeWhile1     , takeTill +    -- ** Consume all remaining input+    , takeText+    , takeLazyText+     -- * Numeric parsers     , decimal     , hexadecimal@@ -62,6 +67,7 @@      -- * State observation and manipulation functions     , endOfInput+    , atEnd     , ensure      -- * Utilities@@ -78,21 +84,51 @@ import Data.String (IsString(..)) import Prelude hiding (getChar, take, takeWhile) import qualified Data.Text as T+import qualified Data.Text.Lazy as TL -data Result r = Fail S [String] String+-- | The result of a parse.+data Result r = Fail T.Text [String] String+              -- ^ The parse failed.  The 'T.Text' is the input+              -- that had not yet been consumed when the failure+              -- occurred.  The @[@'String'@]@ is a list of contexts+              -- in which the error occurred.  The 'String' is the+              -- message describing the error, if any.               | Partial (T.Text -> Result r)-              | Done S r+              -- ^ Supply this continuation with more input so that+              -- the parser can resume.  To indicate that no more+              -- input is available, use an 'T.empty' string.+              | Done T.Text r+              -- ^ The parse succeeded.  The 'T.Text' is the+              -- input that had not yet been consumed (if any) when+              -- the parse succeeded. +instance Show r => Show (Result r) where+    show (Fail bs stk msg) =+        "Fail " ++ show bs ++ " " ++ show stk ++ " " ++ show msg+    show (Partial _)       = "Partial _"+    show (Done bs r)       = "Done " ++ show bs ++ " " ++ show r++fmapR :: (a -> b) -> Result a -> Result b+fmapR _ (Fail st stk msg) = Fail st stk msg+fmapR f (Partial k)       = Partial (fmapR f . k)+fmapR f (Done bs r)       = Done bs (f r)++instance Functor Result where+    fmap = fmapR++newtype Input = I {unI :: T.Text}+newtype Added = A {unA :: T.Text}+ -- | The 'Parser' type is a monad. newtype Parser a = Parser {-      runParser :: forall r. S+      runParser :: forall r. Input -> Added -> More                 -> Failure   r                 -> Success a r                 -> Result r     } -type Failure   r = S -> [String] -> String -> Result r-type Success a r = S -> a -> Result r+type Failure   r = Input -> Added -> More -> [String] -> String -> Result r+type Success a r = Input -> Added -> More -> a -> Result r  instance IsString (Parser T.Text) where     fromString = string . T.pack@@ -101,42 +137,28 @@ data More = Complete | Incomplete             deriving (Eq, Show) -plusMore :: More -> More -> More-plusMore Complete _ = Complete-plusMore _ Complete = Complete-plusMore _ _        = Incomplete-{-# INLINE plusMore #-}--instance Monoid More where-    mempty  = Incomplete-    mappend = plusMore--data S = S {-      input  :: !T.Text-    , _added :: !T.Text-    , more  :: !More-    } deriving (Show)--instance Show r => Show (Result r) where-    show (Fail _ stack msg) = "Fail " ++ show stack ++ " " ++ show msg-    show (Partial _) = "Partial _"-    show (Done bs r) = "Done " ++ show bs ++ " " ++ show r--addS :: S -> S -> S-addS (S s0 a0 c0) (S _s1 a1 c1) = S (s0 +++ a1) (a0 +++ a1) (mappend c0 c1)+addS :: Input -> Added -> More+     -> Input -> Added -> More+     -> (Input -> Added -> More -> r) -> r+addS i0 a0 m0 _i1 a1 m1 f =+    let !i = I (unI i0 +++ unA a1)+        a  = A (unA a0 +++ unA a1)+        !m = m0 <> m1+    in f i a m+  where+    Complete <> _ = Complete+    _ <> Complete = Complete+    _ <> _        = Incomplete {-# INLINE addS #-} -instance Monoid S where-    mempty  = S T.empty T.empty Incomplete-    mappend = addS- bindP :: Parser a -> (a -> Parser b) -> Parser b bindP m g =-    Parser (\st0 kf ks -> runParser m st0 kf (\s a -> runParser (g a) s kf ks))+    Parser $ \i0 a0 m0 kf ks -> runParser m i0 a0 m0 kf $+                                \i1 a1 m1 a -> runParser (g a) i1 a1 m1 kf ks {-# INLINE bindP #-}  returnP :: a -> Parser a-returnP a = Parser (\st0 _kf ks -> ks st0 a)+returnP a = Parser (\i0 a0 m0 _kf ks -> ks i0 a0 m0 a) {-# INLINE returnP #-}  instance Monad Parser where@@ -144,23 +166,26 @@     (>>=)  = bindP     fail   = failDesc -noAdds :: S -> S-noAdds (S s0 _a0 c0) = S s0 T.empty c0+noAdds :: Input -> Added -> More+       -> (Input -> Added -> More -> r) -> r+noAdds i0 _a0 m0 f = f i0 (A T.empty) m0 {-# INLINE noAdds #-}  plus :: Parser a -> Parser a -> Parser a-plus a b = Parser $ \st0 kf ks ->-           let kf' st1 _ _ = runParser b (mappend st0 st1) kf ks-               !st2 = noAdds st0-           in  runParser a st2 kf' ks+plus a b = Parser $ \i0 a0 m0 kf ks ->+           let kf' i1 a1 m1 _ _ = addS i0 a0 m0 i1 a1 m1 $+                                  \ i2 a2 m2 -> runParser b i2 a2 m2 kf ks+           in  noAdds i0 a0 m0 $ \i2 a2 m2 -> runParser a i2 a2 m2 kf' ks {-# INLINE plus #-}  instance MonadPlus Parser where     mzero = failDesc "mzero"+    {-# INLINE mzero #-}     mplus = plus  fmapP :: (a -> b) -> Parser a -> Parser b-fmapP p m = Parser (\st0 f k -> runParser m st0 f (\s a -> k s (p a)))+fmapP p m = Parser $ \i0 a0 m0 f k ->+            runParser m i0 a0 m0 f $ \i1 a1 s1 a -> k i1 a1 s1 (p a) {-# INLINE fmapP #-}  instance Functor Parser where@@ -183,53 +208,67 @@     (*>)   = (>>)     x <* y = x >>= \a -> y >> return a +instance Monoid (Parser a) where+    mempty  = failDesc "mempty"+    {-# INLINE mempty #-}+    mappend = plus+ instance Alternative Parser where     empty = failDesc "empty"+    {-# INLINE empty #-}     (<|>) = plus  failDesc :: String -> Parser a-failDesc err = Parser (\st0 kf _ks -> kf st0 [] msg)+failDesc err = Parser (\i0 a0 m0 kf _ks -> kf i0 a0 m0 [] msg)     where msg = "Failed reading: " ++ err {-# INLINE failDesc #-} --- | Succeed only if at least @n@ characters of input are available.-ensure :: Int -> Parser ()-ensure n = Parser $ \st0@(S s0 _a0 _c0) kf ks ->-    if T.length s0 >= n-    then ks st0 ()-    else runParser (demandInput >> ensure n) st0 kf ks+-- | If at least @n@ bytes of input are available, return the current+-- input, otherwise fail.+ensure :: Int -> Parser T.Text+ensure !n = Parser $ \i0 a0 m0 kf ks ->+    if T.length (unI i0) >= n+    then ks i0 a0 m0 (unI i0)+    else runParser (demandInput >> ensure n) i0 a0 m0 kf ks  -- | Ask for input.  If we receive any, pass it to a success -- continuation, otherwise to a failure continuation.-prompt :: S -> (S -> Result r) -> (S -> Result r) -> Result r-prompt (S s0 a0 _c0) kf ks = Partial $ \s ->+prompt :: Input -> Added -> More+       -> (Input -> Added -> More -> Result r)+       -> (Input -> Added -> More -> Result r)+       -> Result r+prompt i0 a0 _m0 kf ks = Partial $ \s ->     if T.null s-    then kf $! S s0 a0 Complete-    else ks $! S (s0 +++ s) (a0 +++ s) Incomplete+    then kf i0 a0 Complete+    else ks (I (unI i0 +++ s)) (A (unA a0 +++ s)) Incomplete  -- | Immediately demand more input via a 'Partial' continuation -- result. demandInput :: Parser ()-demandInput = Parser $ \st0 kf ks ->-    if more st0 == Complete-    then kf st0 ["demandInput"] "not enough characters"-    else prompt st0 (\st -> kf st ["demandInput"] "not enough characters") (`ks` ())+demandInput = Parser $ \i0 a0 m0 kf ks ->+    if m0 == Complete+    then kf i0 a0 m0 ["demandInput"] "not enough characters"+    else let kf' i a m = kf i a m ["demandInput"] "not enough characters"+             ks' i a m = ks i a m ()+         in prompt i0 a0 m0 kf' ks'  -- | 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 = Parser $ \st0@(S s0 _a0 c0) _kf ks ->+wantInput = Parser $ \i0 a0 m0 _kf ks ->   case () of-    _ | not (T.null s0) -> ks st0 True-      | c0 == Complete  -> ks st0 False-      | otherwise       -> prompt st0 (`ks` False) (`ks` True)+    _ | not (T.null (unI i0)) -> ks i0 a0 m0 True+      | m0 == Complete        -> ks i0 a0 m0 False+      | otherwise             -> let kf' i a m = ks i a m False+                                     ks' i a m = ks i a m True+                                 in prompt i0 a0 m0 kf' ks'  get :: Parser T.Text-get  = Parser (\st0 _kf ks -> ks st0 (input st0))+get  = Parser $ \i0 a0 m0 _kf ks -> ks i0 a0 m0 (unI i0)  put :: T.Text -> Parser ()-put s = Parser (\(S _s0 a0 c0) _kf ks -> ks (S s a0 c0) ())+put s = Parser $ \_i0 a0 m0 _kf ks -> ks (I s) a0 m0 ()  (+++) :: T.Text -> T.Text -> T.Text (+++) = T.append@@ -243,8 +282,10 @@ -- lookahead.  The downside to using this combinator is that it can -- retain input for longer than is desirable. try :: Parser a -> Parser a-try p = Parser $ \st0 kf ks ->-        runParser p (noAdds st0) (kf . mappend st0) ks+try p = Parser $ \i0 a0 m0 kf ks ->+        noAdds i0 a0 m0 $ \i1 a1 m1 ->+            let kf' i2 a2 m2 = addS i0 a0 m0 i2 a2 m2 kf+            in runParser p i1 a1 m1 kf' ks  -- | The parser @satisfy p@ succeeds for any character for which -- the predicate @p@ returns 'True'. Returns the character that@@ -254,8 +295,7 @@ -- >digit = satisfy isDigit satisfy :: (Char -> Bool) -> Parser Char satisfy p = do-  ensure 1-  s <- get+  s <- ensure 1   case T.uncons s of     Just (h,t) | p h       -> put t >> return h                | otherwise -> fail "satisfy"@@ -268,8 +308,7 @@ -- >digit = satisfy isDigit skip :: (Char -> Bool) -> Parser () skip p = do-  ensure 1-  s <- get+  s <- ensure 1   case T.uncons s of     Just (h,t) | p h       -> put t                | otherwise -> fail "skip"@@ -282,8 +321,7 @@ -- character that was parsed. satisfyWith :: (Char -> a) -> (a -> Bool) -> Parser a satisfyWith f p = do-  ensure 1-  s <- get+  s <- ensure 1   let Just (h,t) = T.uncons s       c = f h   if p c@@ -309,8 +347,7 @@ -- predicate returns 'True'. takeWith :: Int -> (T.Text -> Bool) -> Parser T.Text takeWith n p = do-  ensure n-  s <- get+  s <- ensure n   let (h,t) = T.splitAt n s   if p h     then put t >> return h@@ -352,11 +389,12 @@ skipWhile p = go  where   go = do-    input <- wantInput-    when input $ do-      t <- T.dropWhile p <$> get-      put t-      when (T.null t) go+    t <- T.dropWhile p <$> get+    put t+    when (T.null t) $ do+      input <- wantInput+      when input go+{-# INLINE skipWhile #-}  -- | Skip over white space. skipSpace :: Parser ()@@ -386,26 +424,80 @@ -- combinators such as 'many', because such parsers loop until a -- failure occurs.  Careless use will thus result in an infinite loop. takeWhile :: (Char -> Bool) -> Parser T.Text-takeWhile p = go []+takeWhile p = (T.concat . reverse) `fmap` go []  where   go acc = do-    input <- wantInput-    if input-      then do #if MIN_VERSION_text(0,11,0)-        (h,t) <- T.span p <$> get+    (h,t) <- T.span p <$> get #else-        (h,t) <- T.spanBy p <$> get+    (h,t) <- T.spanBy p <$> get #endif-        put t-        if T.null t+    put t+    if T.null t+      then do+        input <- wantInput+        if input           then go (h:acc)-          else return $ if null acc then h else T.concat $ reverse (h:acc)-      else return $ case acc of-                      []  -> T.empty-                      [x] -> x-                      _   -> T.concat $ reverse acc+          else return (h:acc)+      else return (h:acc) +takeRest :: Parser [T.Text]+takeRest = go []+ where+  go acc = do+    input <- wantInput+    if input+      then do+        s <- get+        put T.empty+        go (s:acc)+      else return (reverse acc)++-- | Consume all remaining input and return it as a single string.+takeText :: Parser T.Text+takeText = T.concat `fmap` takeRest++-- | Consume all remaining input and return it as a single string.+takeLazyText :: Parser TL.Text+takeLazyText = TL.fromChunks `fmap` takeRest++-- | 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 character of the input until one+-- returns 'Nothing' or the input ends.+--+-- This parser does not fail.  It will return an empty string if the+-- predicate returns 'Nothing' on the first character of input.+--+-- /Note/: Because this parser does not fail, do not use it with+-- combinators such as 'many', because such parsers loop until a+-- failure occurs.  Careless use will thus result in an infinite loop.+scan :: s -> (s -> Char -> Maybe s) -> Parser T.Text+scan s0 p = do+  chunks <- go [] s0+  case chunks of+    [x] -> return x+    xs  -> return . T.concat . reverse $ xs+ where+  scanner s !n t =+    case T.uncons t of+      Nothing     -> Continue s+      Just (c,t') -> case p s c of+                       Just s' -> scanner s' (n+1) t'+                       Nothing -> Finished n t+  go acc s = do+    input <- get+    case scanner s 0 input of+      Continue s'  -> do put T.empty+                         more <- wantInput+                         if more+                           then go (input : acc) s'+                           else return (input : acc)+      Finished n t -> put t >> return (T.take n input : acc)+{-# INLINE scan #-}++data ScannnerResult s = Continue s | Finished !Int !T.Text+ -- | Consume input as long as the predicate returns 'True', and return -- the consumed input. --@@ -576,15 +668,24 @@  -- | Match only if all input has been consumed. endOfInput :: Parser ()-endOfInput = Parser $ \st0@S{..} kf ks ->-             if T.null input-             then if more == Complete-                  then ks st0 ()-                  else let kf' st1 _ _ = ks (mappend st0 st1) ()-                           ks' st1 _   = kf (mappend st0 st1) [] "endOfInput"-                       in  runParser demandInput st0 kf' ks'-             else kf st0 [] "endOfInput"+endOfInput = Parser $ \i0 a0 m0 kf ks ->+             if T.null (unI i0)+             then if m0 == Complete+                  then ks i0 a0 m0 ()+                  else let kf' i1 a1 m1 _ _ = addS i0 a0 m0 i1 a1 m1 $+                                              \ i2 a2 m2 -> ks i2 a2 m2 ()+                           ks' i1 a1 m1 _   = addS i0 a0 m0 i1 a1 m1 $+                                              \ i2 a2 m2 -> kf i2 a2 m2 []+                                                            "endOfInput"+                       in  runParser demandInput i0 a0 m0 kf' ks'+             else kf i0 a0 m0 [] "endOfInput" +-- | Return an indication of whether the end of input has been+-- reached.+atEnd :: Parser Bool+atEnd = not <$> wantInput+{-# INLINE atEnd #-}+ -- | Match either a single newline character @\'\\n\'@, or a carriage -- return followed by a newline character @\"\\r\\n\"@. endOfLine :: Parser ()@@ -594,19 +695,31 @@ (<?>) :: Parser a       -> String                 -- ^ the name to use if parsing fails       -> Parser a-p <?> msg = Parser $ \s kf ks -> runParser p s (\s' strs m -> kf s' (msg:strs) m) ks+p <?> msg0 = Parser $ \i0 a0 m0 kf ks ->+             let kf' i a m strs msg = kf i a m (msg0:strs) msg+             in runParser p i0 a0 m0 kf' ks {-# INLINE (<?>) #-} infix 0 <?>  -- | Terminal failure continuation. failK :: Failure a-failK st0 stack msg = Fail st0 stack msg+failK i0 _a0 _m0 stack msg = Fail (unI i0) stack msg+{-# INLINE failK #-}  -- | Terminal success continuation. successK :: Success a a-successK state a = Done state a+successK i0 _a0 _m0 a = Done (unI i0) a+{-# INLINE successK #-}  -- | Run a parser. parse :: Parser a -> T.Text -> Result a-parse m s = runParser m (S s T.empty Incomplete) failK successK+parse m s = runParser m (I s) (A T.empty) Incomplete failK successK {-# INLINE parse #-}++-- | Run a parser that cannot be resupplied via a 'Partial' result.+parseOnly :: Parser a -> T.Text -> Either String a+parseOnly m s = case runParser m (I s) (A T.empty) Complete failK successK of+                  Fail _ _ err -> Left err+                  Done _ a     -> Right a+                  _            -> error "parseOnly: impossible error!"+{-# INLINE parseOnly #-}
attoparsec-text.cabal view
@@ -1,5 +1,5 @@ name:            attoparsec-text-version:         0.8.2.1+version:         0.8.5.0 license:         BSD3 license-file:    LICENSE category:        Text, Parsing@@ -10,7 +10,6 @@ synopsis:        Fast combinator parsing for texts cabal-version:   >= 1.6 homepage:        http://patch-tag.com/r/felipe/attoparsec-text/home--- bug-reports:     http://bitbucket.org/bos/attoparsec/issues build-type:      Simple description:     A fast parser combinator library, aimed particularly at dealing@@ -20,6 +19,10 @@     This library is basically a translation of the original     attoparsec library to use text instead of bytestrings.     .+    Changes in version 0.8.5.0:+    .+    * Ported changes from attoparsec 0.8.5.0.+    .     Changes in version 0.8.2.1:     .     * Permit newer version of containers for GHC 7.0.@@ -49,6 +52,10 @@ --    examples/RFC2616.hs --    examples/TestRFC2616.hs --    examples/rfc2616.c++source-repository head+  type: darcs+  location: http://patch-tag.com/r/felipe/attoparsec-text  library   build-depends: base       >= 3       && < 5,
benchmarks/Double.hs view
@@ -3,12 +3,25 @@ import Data.Char (isDigit, isLetter) import Data.List (foldl') import System.Environment (getArgs)+import qualified Data.Attoparsec.Char8 as AB import qualified Data.Attoparsec.Text as A+import qualified Data.ByteString.Char8 as B import qualified Data.Text as T import qualified Data.Text.IO as T import qualified Data.Text.Read as TR import qualified Text.ParserCombinators.Parsec as P +attoparsec_builtin args = do+  forM_ args $ \arg -> do+    input <- B.readFile arg+    case AB.parse (AB.many1 (AB.char '#' >> p)) input `AB.feed` B.empty of+      AB.Done _ xs -> print (sum xs :: Double)+      what        -> print what+ where+  p = AB.double++----------------------------------------------------------------------+ attoparsec_text_builtin args = do   forM_ args $ \arg -> do     input <- T.readFile arg@@ -85,6 +98,7 @@ main = do   args <- getArgs   case args of+    ("attoparsec_builtin":xs) -> attoparsec_builtin xs     ("attoparsec_text_builtin":xs) -> attoparsec_text_builtin xs     ("attoparsec_text_laforge":xs) -> attoparsec_text_laforge xs     ("attoparsec_text_laforge_discarding":xs) -> attoparsec_text_laforge_discarding xs