iteratee-parsec 0.0.3 → 0.0.4
raw patch · 4 files changed
+110/−110 lines, 4 filesdep ~iterateedep ~parsec
Dependency ranges changed: iteratee, parsec
Files
- iteratee-parsec.cabal +4/−4
- src/Text/Parsec/Iteratee.hs +1/−1
- src/Text/Parsec/Iteratee/Chunk.hs +28/−31
- src/Text/Parsec/Iteratee/LinkedList.hs +77/−74
iteratee-parsec.cabal view
@@ -1,8 +1,8 @@ Name: iteratee-parsec-Version: 0.0.3+Version: 0.0.4 Synopsis: Package allowing parsec parser initeratee Description: Package providing instances of Stream in- IterateeG monad.+ Iteratee monad. Category: Data, Parsing License: MIT License-file: LICENSE@@ -14,9 +14,9 @@ Library Build-Depends: base >= 3 && < 5,- iteratee >= 0.3.5 && < 0.4,+ iteratee >= 0.4 && < 0.5, ListLike >= 1.0 && < 2,- parsec >= 3 && < 3.2,+ parsec >= 3.1 && < 3.2, transformers >= 0.2.0.0 && < 0.3 Exposed-Modules: Text.Parsec.Iteratee, Text.Parsec.Iteratee.Chunk,
src/Text/Parsec/Iteratee.hs view
@@ -1,6 +1,6 @@ {- | Module : $Header$-Description : Module providing implementations of Stream in IterateeG monad.+Description : Module providing implementations of Stream in Iteratee monad. Copyright : (c) Maciej Piechotka License : MIT
src/Text/Parsec/Iteratee/Chunk.hs view
@@ -22,26 +22,24 @@ ) where -import qualified Data.Iteratee as I-import Data.Iteratee.Base (IterateeG (..), StreamG (..), IterGV (..))-import qualified Data.Iteratee.Base.StreamChunk as SC-import Control.Monad import Control.Applicative+import Control.Monad+import Data.Iteratee as I import qualified Data.ListLike as LL import Data.Monoid-import Text.Parsec+import Text.Parsec hiding (Stream)+import qualified Text.Parsec as P -- |Create an Iteratee from a ParsecT parser. -- This is most efficient for relatively smaller parsers (< 1e5 chars), -- and becomes increasingly inefficient as the parser size increases. -- If the parse fails, no input is consumed. If the parse succeeds, -- any data remaining after the parse is available to the iteratee.-safeParsecIterateeShort- :: (Stream Int (IterateeG s t m) t, Monad m, SC.StreamChunk s t) =>- ParsecT Int u (IterateeG s t m) a- -> u- -> SourceName- -> IterateeG s t m (Either ParseError a)+safeParsecIterateeShort :: (Monad m, Nullable s, LL.ListLike s t)+ => ParsecT Int u (Iteratee s m) a+ -> u+ -> SourceName+ -> Iteratee s m (Either ParseError a) safeParsecIterateeShort p u sn = do res <- runParserT ((,) <$> p <*> getInput ) u sn 0 case res of@@ -50,29 +48,28 @@ -- |Make an Iteratee instance of Parsec's Stream class. -- This is only efficient for relatively small parsers (on order of 1e5 chars).-instance (Monad m, SC.StreamChunk s el) =>- Stream Int (IterateeG s el m) el where+instance (Monad m, Nullable s, LL.ListLike s el) =>+ P.Stream Int (Iteratee s m) el where uncons n = (liftM . fmap) (\res -> (res, n+1)) $ peekAt n -- |Peek @n@ points ahead into the stream. This will force chunks if -- necessary.-peekAt :: (SC.StreamChunk s el, Monad m) => Int -> IterateeG s el m (Maybe el)+peekAt :: (LL.ListLike s el, Nullable s, Monad m)+ => Int -> Iteratee s m (Maybe el) peekAt 0 = I.peek-peekAt n = IterateeG step- where- step c@(Chunk xs)- | SC.null xs = return $ Cont (peekAt n) Nothing- | n < SC.length xs = return $ Done (Just $ LL.index xs n) c- | True = return $ Cont (nextChunk xs) Nothing- step str = return $ Done Nothing str- nextChunk xs = IterateeG step2- where- step2 (Chunk xs')- | SC.null xs' = return $ Cont (nextChunk xs) Nothing- | n < (SC.length xs + SC.length xs') =- let nxs = xs `mappend` xs'- in return $ Done (Just $ LL.index nxs n) (Chunk nxs)- | True = let nxs = xs `mappend` xs'- in return $ Cont (nextChunk nxs) Nothing- step2 str = return $ Done Nothing str+peekAt n = liftI step+ where step c@(Chunk xs)+ | LL.null xs = liftI step+ | n < LL.length xs = idone (Just $ LL.index xs n) c+ | otherwise = liftI (nextChunk xs)+ step (EOF Nothing) = return Nothing+ step (EOF (Just err)) = throwErr err+ + nextChunk xs (Chunk xs')+ | LL.null xs' = liftI (nextChunk xs)+ | n < LL.length nxs = idone (Just $ LL.index nxs n) (Chunk nxs)+ | otherwise = liftI (nextChunk nxs)+ where nxs = xs `mappend` xs'+ nextChunk xs (EOF Nothing) = idone Nothing (Chunk xs)+ nextChunk _ (EOF (Just err)) = throwErr err
src/Text/Parsec/Iteratee/LinkedList.hs view
@@ -32,11 +32,11 @@ import Control.Monad.Trans.Class import Data.Monoid import Data.Iteratee-import Data.Iteratee.Base.StreamChunk (StreamChunk) import Data.IORef-import qualified Data.ListLike as LL+import Data.ListLike as LL import Data.STRef-import Text.Parsec+import Text.Parsec hiding (Stream)+import qualified Text.Parsec as P -- | Class notifing a reference in monad. -- Probably should be in separate module.@@ -59,118 +59,121 @@ modifyRef r f = readRef r >>= f >>= \(a, b) -> writeRef r a >> return b instance Reference IORef IO where- newRef = newIORef- readRef = readIORef- writeRef = writeIORef+ newRef = newIORef+ readRef = readIORef+ writeRef = writeIORef instance Reference (STRef s) (ST s) where- newRef = newSTRef- readRef = readSTRef- writeRef = writeSTRef+ newRef = newSTRef+ readRef = readSTRef+ writeRef = writeSTRef instance Reference MVar IO where- newRef = newMVar- readRef = readMVar- writeRef = putMVar+ newRef = newMVar+ readRef = readMVar+ writeRef = putMVar -- | Specify the 3 possible states of next cursor - existence, non-existence -- and not being evaluated-data (Monad m, Reference r m, StreamChunk c el) => NextCursor r m c el- -- | Points to next cursor- = NextCursor (Cursor r m c el)- -- | States that next cursor does not exists- | None- -- | Next cursor is not evaluated- | Uneval+data (Monad m, Reference r m, ListLike s el) => NextCursor r m s el+ -- | Points to next cursor+ = NextCursor (Cursor r m s el)+ -- | States that next cursor does not exists+ | None+ -- | Next cursor is not evaluated+ | Uneval -- | Cursor holds current value and reference to possible next cursor-data (Monad m, Reference r m, StreamChunk c el) => Cursor r m c el = - Cursor (r (NextCursor r m c el)) (c el)+data (Monad m, Reference r m) => Cursor r m s el+ = Cursor (r (NextCursor r m s el)) s -- | Creates new cursor-mkCursor :: (Monad m, Reference r m, StreamChunk c el) => m (Cursor r m c el)-mkCursor = newRef Uneval >>= \r -> (return $! Cursor r LL.empty)+mkCursor :: (Monad m, Reference r m, ListLike s el) => m (Cursor r m s el)+mkCursor = (\r -> return $! Cursor r LL.empty) =<< newRef Uneval -instance (Monad m, Reference r m, StreamChunk c el) =>- Stream (Cursor r m c el) (IterateeG c el m) el where+instance (Monad m, Nullable s, Reference r m, ListLike s el) =>+ P.Stream (Cursor r m s el) (Iteratee s m) el where uncons = unconsStream -unconsStream :: (Monad m, Reference r m, StreamChunk c el)- => Cursor r m c el- -> IterateeG c el m (Maybe (el, Cursor r m c el))+unconsStream :: (Monad m, Nullable s, Reference r m, ListLike s el)+ => Cursor r m s el+ -> Iteratee s m (Maybe (el, Cursor r m s el)) unconsStream p@(Cursor r c)- | LL.null c = IterateeG $ \st -> join $ modifyRef r $ unconsCursor st p- | otherwise = return $! justUnconsCursor p+ | LL.null c = unconsCursor r =<< lift (readRef r)+ | otherwise = return $! unconsChunk p -unconsCursor :: forall r m c el. (Monad m, Reference r m, StreamChunk c el)- => StreamG c el- -> Cursor r m c el- -> NextCursor r m c el- -> m (NextCursor r m c el,- m (IterGV c el m (Maybe (el, Cursor r m c el))))-unconsCursor st _ rv@(NextCursor p@(Cursor r c))- | LL.null c = return $! (rv, join $ modifyRef r $ unconsCursor st p)- | otherwise = return $! (rv, return $! Done (justUnconsCursor p) st)-unconsCursor st _ rv@None- = return $! (rv, return $! Done Nothing st)-unconsCursor (Chunk c) p rv@Uneval- | LL.null c = return $! (rv, return $! Cont (unconsStream p) Nothing)- | otherwise = do r <- newRef Uneval :: m (r (NextCursor r m c el))- let p' = Cursor r c- ra = Done (justUnconsCursor p') (Chunk LL.empty)- return $! (NextCursor p', return $! ra)-unconsCursor st@(EOF Nothing) _ Uneval- = return $! (None, return $! Done Nothing st)-unconsCursor (EOF (Just e)) _ rv@Uneval- = return $! (rv, return $! Cont (throwErr e) (Just e))+unconsCursor :: (Monad m, Nullable s, Reference r m, ListLike s el)+ => r (NextCursor r m s el)+ -> NextCursor r m s el+ -> Iteratee s m (Maybe (el, Cursor r m s el))+unconsCursor _ (NextCursor c) = return $! unconsChunk c+unconsCursor _ None = return $! Nothing+unconsCursor r Uneval = icont (extendCursor r) Nothing -justUnconsCursor :: (Monad m, Reference r m, StreamChunk c el) =>- Cursor r m c el -> Maybe (el, Cursor r m c el)-justUnconsCursor (Cursor r c) = Just $! (LL.head c, Cursor r $ LL.tail c)+insertCursor :: (Monad m, Reference r m, ListLike s el)+ => r (NextCursor r m s el)+ -> s+ -> m (Cursor r m s el)+insertCursor r s = do+ r' <- newRef Uneval+ let c = Cursor r' s+ writeRef r (NextCursor c)+ return c -concatCursor :: (Monad m, Reference r m, StreamChunk c el)- => Cursor r m c el -> m (c el)-concatCursor c = liftM mconcat (concatCursor' c)+extendCursor :: (Monad m, Nullable s, Reference r m, ListLike s el)+ => r (NextCursor r m s el)+ -> Stream s+ -> Iteratee s m (Maybe (el, Cursor r m s el))+extendCursor r (Chunk s)+ | LL.null s = liftI (extendCursor r)+ | otherwise = return . unconsChunk =<< lift (insertCursor r s)+extendCursor r (EOF Nothing)+ = const (return Nothing) =<< lift (writeRef r None)+extendCursor _ (EOF (Just e))+ = throwErr e -concatCursor' :: (Monad m, Reference r m, StreamChunk c el)- => Cursor r m c el -> m [c el]-concatCursor' (Cursor r v) =- liftM2 (:) (return v) (readRef r >>= concatNextCursor')+unconsChunk :: (Monad m, Reference r m, ListLike s el)+ => Cursor r m s el -> Maybe (el, Cursor r m s el)+unconsChunk (Cursor r s) = Just (LL.head s, Cursor r $ LL.tail s) -concatNextCursor' :: (Monad m, Reference r m, StreamChunk c el)- => NextCursor r m c el -> m [c el]-concatNextCursor' (NextCursor c) = concatCursor' $! c-concatNextCursor' _ = return $! []+concatCursor :: (Monad m, Reference r m, ListLike s el)+ => Cursor r m s el -> m s+concatCursor (Cursor r s) = liftM (s `mappend`) (concatCursor' =<< readRef r) +concatCursor' :: (Monad m, Reference r m, ListLike s el)+ => NextCursor r m s el -> m s+concatCursor' (NextCursor n) = concatCursor n+concatCursor' _ = return $! mempty+ -- | Runs parser. If it suceed the remaining part of stream stands in stream, -- however if it fails the stream is not in defined state.-parsecIteratee :: (Monad m, Reference r m, StreamChunk c el)- => ParsecT (Cursor r m c el) u (IterateeG c el m) a+parsecIteratee :: (Monad m, Reference r m, Nullable c, ListLike c el)+ => ParsecT (Cursor r m c el) u (Iteratee c m) a -- ^ Parser to run -> u -- ^ A user state -> SourceName -- ^ Source name- -> IterateeG c el m (Either ParseError a)+ -> Iteratee c m (Either ParseError a) parsecIteratee p u sn = do c <- lift mkCursor res <- runParserT (liftM2 (,) p getInput) u sn c case res of Right (a, c') -> do sc <- lift $ concatCursor c'- liftI $! Done (Right a) $! Chunk $! sc- Left err -> return $ Left err+ idone (Right a) (Chunk sc)+ Left err -> return $! Left err -- | Runs parser. If it suceed the remaining part of stream stands in stream, -- however if it fails everything stands in stream.-safeParsecIteratee :: (Monad m, Reference r m, StreamChunk c el)- => ParsecT (Cursor r m c el) u (IterateeG c el m) a+safeParsecIteratee :: (Monad m, Reference r m, Nullable c, ListLike c el)+ => ParsecT (Cursor r m c el) u (Iteratee c m) a -- ^ Parser to run -> u -- ^ A user state -> SourceName -- ^ Source name- -> IterateeG c el m (Either ParseError a)+ -> Iteratee c m (Either ParseError a) safeParsecIteratee p u sn = do c <- lift mkCursor Right (c', res) <- runParserT (parsecSafe p) u sn c sc <- lift $ concatCursor c'- liftI $! Done res $! Chunk $! sc+ idone res (Chunk sc) parsecSafe :: Monad m => ParsecT s u m a