Skip to content

Loading…

Update to newer version of iteratee #2

Merged
1 commit merged into from

2 participants

@uzytkownik

I have updated to new version of iteratee

@gregorycollins

Hi,

Unfortunately your implementation has a little bug. Attoparsec has an interesting quirk whereby if you feed "parse" a null string, it responds with "Atto.Partial" even if the parser should match empty string. This is why the old code had this for the EOF case:

f k (EOF Nothing)  = finalChunk $ feed (k S.empty) S.empty

IOW you have to feed the continuation two empty strings to make 100% sure it transitions properly to the "Done" state.

Could you make this small change and resend? I will then release your code as 0.2. Thanks for sending this and my apologies for not getting back to you sooner (holidays).

@uzytkownik

I've added the change.

Regards

@gregorycollins

Thanks Maciej!

Would you like to take over maintainership of this package? I don't use iteratee anymore.

@uzytkownik

Sorry for delay in responding. Unfortunatly I'm afraid that I have too less time for things I'm maintaining right now.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 5, 2011
  1. @uzytkownik
Showing with 26 additions and 64 deletions.
  1. +2 −2 attoparsec-iteratee.cabal
  2. +24 −62 src/Data/Attoparsec/Iteratee.hs
View
4 attoparsec-iteratee.cabal
@@ -1,5 +1,5 @@
name: attoparsec-iteratee
-version: 0.1.2
+version: 0.2.0
synopsis: An adapter to convert attoparsec Parsers into blazing-fast Iteratees
description:
An adapter to convert attoparsec Parsers into blazing-fast Iteratees
@@ -23,7 +23,7 @@ Library
attoparsec >= 0.8 && < 0.9,
base >= 4 && < 5,
bytestring,
- iteratee >= 0.3.1 && <0.4,
+ iteratee >= 0.7 && <0.8,
monads-fd,
transformers
View
86 src/Data/Attoparsec/Iteratee.hs
@@ -1,76 +1,38 @@
+{-# LANGUAGE DeriveDataTypeable #-}
module Data.Attoparsec.Iteratee
- ( parserToIteratee ) where
+ ( ParseError(..), parserToIteratee ) where
------------------------------------------------------------------------------
+import Control.Exception
import qualified Data.Attoparsec as Atto
import Data.Attoparsec hiding (many, Result(..))
import Data.ByteString (ByteString)
-import qualified Data.ByteString as S
-import qualified Data.ByteString.Lazy as L
+import qualified Data.ByteString as B
import Data.Iteratee
-import Data.Iteratee.WrappedByteString
-import Data.Word
+import Data.Typeable
------------------------------------------------------------------------------
-type Stream = StreamG WrappedByteString Word8
-type IterV m = IterGV WrappedByteString Word8 m
+data ParseError
+ = ParseError {errorContexts :: [String], errorMessage :: String}
+ deriving (Show, Typeable)
+instance Exception ParseError
parserToIteratee :: (Monad m) =>
Parser a
- -> IterateeG WrappedByteString Word8 m a
-parserToIteratee p = IterateeG $ f (\s -> parse p s)
- where
- f :: (Monad m) =>
- (ByteString -> Atto.Result a)
- -> Stream
- -> m (IterV m a)
- f k (EOF Nothing) = finalChunk $ feed (k S.empty) S.empty
- f _ (EOF (Just e)) = reportError e
- f k (Chunk s) = let s' = S.concat $ L.toChunks $ fromWrap s
- in if S.null s'
- then return $ Cont (IterateeG $ f k) Nothing
- else chunk s' k
-
-
- finalChunk :: (Monad m) => Atto.Result a -> m (IterV m a)
- finalChunk (Atto.Fail _ _ m) =
- return $ Cont (error $ show m)
- (Just $ Err m)
-
- finalChunk (Atto.Done rest r)
- | S.null rest =
- return $ Done r (EOF Nothing)
- | otherwise =
- return $ Done r (Chunk $ toWrap $ L.fromChunks [rest])
-
- finalChunk (Atto.Partial _) =
- return $ Cont (error "parser did not produce a value")
- (Just $ Err "parser did not produce a value")
-
- reportError e = return $ Cont (error $ show e) (Just e)
-
- chunk :: (Monad m) =>
- ByteString
- -> (ByteString -> Atto.Result a)
- -> m (IterV m a)
- chunk s k = do
- let r = k s
- case r of
- (Atto.Fail _ _ m) -> return $
- Cont (throwErr (Err m)) (Just $ Err m)
- (Atto.Done rest x) -> return $ Done x (Chunk $ toWrap $ L.fromChunks [rest])
- (Atto.Partial z) -> return $
- Cont (IterateeG $ f z) Nothing
-
-
--- | lazy bytestring -> wrapped bytestring
-toWrap :: L.ByteString -> WrappedByteString Word8
-toWrap = WrapBS . S.concat . L.toChunks
-{-# INLINE toWrap #-}
-
--- | wrapped bytestring -> lazy bytestring
-fromWrap :: WrappedByteString Word8 -> L.ByteString
-fromWrap = L.fromChunks . (:[]) . unWrap
-{-# INLINE fromWrap #-}
+ -> Iteratee ByteString m a
+parserToIteratee p = icont (f (parse p)) Nothing
+ where f k (EOF Nothing) = case feed (k B.empty) B.empty of
+ Atto.Fail _ err dsc -> throwErr (toException $ ParseError err dsc)
+ Atto.Partial _ -> throwErr (toException EofException)
+ Atto.Done rest v
+ | B.null rest -> idone v (EOF Nothing)
+ | otherwise -> idone v (Chunk rest)
+ f _ (EOF (Just e)) = throwErr e
+ f k (Chunk s)
+ | B.null s = icont (f k) Nothing
+ | otherwise = case k s of
+ Atto.Fail _ err dsc -> throwErr (toException $ ParseError err dsc)
+ Atto.Partial k' -> icont (f k') Nothing
+ Atto.Done rest v -> idone v (Chunk rest)
Something went wrong with that request. Please try again.