module Hidden.ParseLibCore (
Parse
, runParse
, MonadParse(spot, spotBack, still, parseNot, askHere)
, MonadPlus(mzero, mplus)
, MonadReader(ask, local)
) where
import Control.Monad.Trans ( lift )
import Control.Monad ( MonadPlus(mzero, mplus) )
import Control.Monad.Reader( MonadReader(ask,local),
ReaderT(ReaderT, runReaderT), mapReaderT )
import Control.Monad.Writer( WriterT(WriterT, runWriterT), mapWriterT )
import Control.Monad.State ( StateT (StateT, runStateT ), mapStateT )
import Data.Monoid ( Monoid(mempty) )
class Monad m => MonadParse a m | m -> a where
spot :: (a -> Bool) -> m a
spotBack :: (a -> Bool) -> m a
still :: m b -> m b
parseNot :: b -> m b -> m b
askHere :: m ([a],[a])
instance (MonadParse a m) => MonadParse a (ReaderT s m) where
spot = lift . spot
spotBack = lift . spotBack
still = mapReaderT still
parseNot x p = ReaderT $ \r -> parseNot x (runReaderT p r)
askHere = lift askHere
instance (MonadParse a m, Monoid w) => MonadParse a (WriterT w m) where
spot = lift . spot
spotBack = lift . spotBack
still = mapWriterT still
parseNot x p = WriterT $ parseNot (x, mempty) (runWriterT p)
askHere = lift askHere
instance (MonadParse a m) => MonadParse a (StateT r m) where
spot = lift . spot
spotBack = lift . spotBack
still = mapStateT still
parseNot x p = StateT $ \s -> parseNot (x,s) (runStateT p s)
askHere = lift askHere
newtype Parse a b = Parse { runParse :: ([a],[a]) -> [(b,([a],[a]))] }
instance MonadParse a (Parse a) where
spot = Parse . spt
where
spt p (pre,(x:xs))
| p x = [(x,(x:pre,xs))]
| otherwise = []
spt _ (_,[]) = []
spotBack = Parse . sptbck
where
sptbck p ((x:xs),post)
| p x = [(x,(xs,x:post))]
| otherwise = []
sptbck _ ([],_) = []
still p = Parse $ \inp -> do (ret,_) <- runParse p inp
return (ret,inp)
parseNot x (Parse p) = Parse $ \inp -> case p inp of
[] -> [(x,inp)]
_ -> []
askHere = ask
instance Monad (Parse a) where
return = Parse . \val inp -> [(val,inp)]
(Parse pr) >>= f
= Parse (\st -> concat [ runParse (f a) rest | (a,rest) <- pr st ])
instance MonadPlus (Parse a) where
mzero = Parse $ const []
Parse p1 `mplus` Parse p2 = Parse $ \inp -> p1 inp ++ p2 inp
instance MonadReader ([a],[a]) (Parse a) where
ask = Parse $ \inp -> [(inp,inp)]
local f m = Parse $ runParse m . f