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 +47/−52
- Data/Attoparsec/Text/Internal.hs +217/−104
- attoparsec-text.cabal +9/−2
- benchmarks/Double.hs +14/−0
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