module Text.Syntax.Parser.List.LazyMaybe (
Parser, runParser,
runAsParser
) where
import Control.Applicative (Alternative(empty, (<|>)))
import Control.Monad (MonadPlus(mzero, mplus), ap, liftM)
#if __GLASGOW_HASKELL__ < 710
import Control.Applicative (Applicative(pure, (<*>)))
#endif
import Text.Syntax.Parser.Instances ()
import Text.Syntax.Poly.Class
(TryAlternative, Syntax (token))
import Text.Syntax.Parser.List.Type (RunAsParser, ErrorString, errorString)
newtype Parser tok alpha =
Parser {
runParser :: [tok] -> Maybe (alpha, [tok])
}
instance Functor (Parser tok) where
fmap = liftM
instance Applicative (Parser tok) where
pure = return
(<*>) = ap
instance Monad (Parser tok) where
return a = Parser $ \s -> Just (a, s)
Parser p >>= fb = Parser (\s -> do (a, s') <- p s
runParser (fb a) s')
fail = const mzero
instance Alternative (Parser tok) where
empty = mzero
(<|>) = mplus
instance MonadPlus (Parser tok) where
mzero = Parser $ const Nothing
Parser p1 `mplus` p2' =
Parser (\s -> p1 s `mplus` runParser p2' s)
instance TryAlternative (Parser tok)
instance Eq tok => Syntax tok (Parser tok) where
token = Parser (\s -> case s of
t:ts -> Just (t, ts)
[] -> Nothing)
runAsParser :: Eq tok => RunAsParser tok a ErrorString
runAsParser parser s = case runParser parser s of
Just (a, []) -> Right a
Just (_, (_:_)) -> Left . errorString $ "Not the end of token stream."
Nothing -> Left . errorString $ "parse error"