{-# LANGUAGE CPP #-} {-# LANGUAGE UndecidableInstances #-} #if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 704 #define USE_DEFAULT_SIGNATURES #endif #ifdef USE_DEFAULT_SIGNATURES {-# LANGUAGE DefaultSignatures, TypeFamilies #-} #endif ----------------------------------------------------------------------------- -- | -- Module : Text.Parser.LookAhead -- Copyright : (c) Edward Kmett 2011-2013 -- License : BSD3 -- -- Maintainer : ekmett@gmail.com -- Stability : experimental -- Portability : non-portable -- -- Parsers that can 'lookAhead'. ----------------------------------------------------------------------------- module Text.Parser.LookAhead ( -- * Parsing Combinators LookAheadParsing(..) ) where import Control.Monad (MonadPlus(..)) import Control.Monad.Trans.State.Lazy as Lazy import Control.Monad.Trans.State.Strict as Strict import Control.Monad.Trans.Writer.Lazy as Lazy import Control.Monad.Trans.Writer.Strict as Strict import Control.Monad.Trans.RWS.Lazy as Lazy import Control.Monad.Trans.RWS.Strict as Strict import Control.Monad.Trans.Reader import Control.Monad.Trans.Identity import qualified Data.Attoparsec.Types as Att import qualified Data.Attoparsec.Combinator as Att #if __GLASGOW_HASKELL__ < 710 import Data.Monoid #endif import qualified Text.ParserCombinators.ReadP as ReadP import qualified Text.Parsec as Parsec import Text.Parser.Combinators -- | Additional functionality needed to describe parsers independent of input type. class Parsing m => LookAheadParsing m where -- | @lookAhead p@ parses @p@ without consuming any input. lookAhead :: m a -> m a instance (LookAheadParsing m, MonadPlus m) => LookAheadParsing (Lazy.StateT s m) where lookAhead (Lazy.StateT m) = Lazy.StateT $ lookAhead . m {-# INLINE lookAhead #-} instance (LookAheadParsing m, MonadPlus m) => LookAheadParsing (Strict.StateT s m) where lookAhead (Strict.StateT m) = Strict.StateT $ lookAhead . m {-# INLINE lookAhead #-} instance (LookAheadParsing m, MonadPlus m) => LookAheadParsing (ReaderT e m) where lookAhead (ReaderT m) = ReaderT $ lookAhead . m {-# INLINE lookAhead #-} instance (LookAheadParsing m, MonadPlus m, Monoid w) => LookAheadParsing (Strict.WriterT w m) where lookAhead (Strict.WriterT m) = Strict.WriterT $ lookAhead m {-# INLINE lookAhead #-} instance (LookAheadParsing m, MonadPlus m, Monoid w) => LookAheadParsing (Lazy.WriterT w m) where lookAhead (Lazy.WriterT m) = Lazy.WriterT $ lookAhead m {-# INLINE lookAhead #-} instance (LookAheadParsing m, MonadPlus m, Monoid w) => LookAheadParsing (Lazy.RWST r w s m) where lookAhead (Lazy.RWST m) = Lazy.RWST $ \r s -> lookAhead (m r s) {-# INLINE lookAhead #-} instance (LookAheadParsing m, MonadPlus m, Monoid w) => LookAheadParsing (Strict.RWST r w s m) where lookAhead (Strict.RWST m) = Strict.RWST $ \r s -> lookAhead (m r s) {-# INLINE lookAhead #-} instance (LookAheadParsing m, Monad m) => LookAheadParsing (IdentityT m) where lookAhead = IdentityT . lookAhead . runIdentityT {-# INLINE lookAhead #-} instance (Parsec.Stream s m t, Show t) => LookAheadParsing (Parsec.ParsecT s u m) where lookAhead = Parsec.lookAhead instance Att.Chunk i => LookAheadParsing (Att.Parser i) where lookAhead = Att.lookAhead instance LookAheadParsing ReadP.ReadP where lookAhead p = ReadP.look >>= \s -> ReadP.choice $ map (return . fst) $ ReadP.readP_to_S p s