module Text.Syntax.Parser.List.Lazy (
Parser, runParser, ErrorStack,
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.Instances ()
import Text.Syntax.Poly.Class
(TryAlternative, Syntax (..))
import Text.Syntax.Parser.List.Type (RunAsParser, ErrorStack, errorString)
newtype Parser tok alpha =
Parser {
runParser :: [tok] -> ErrorStack -> Either ErrorStack (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 _ -> Right (a, s)
Parser p >>= fb = Parser (\s e -> do (a, s') <- p s e
runParser (fb a) s' e)
fail msg = Parser (\_ e -> Left $ errorString msg : e)
instance Alternative (Parser tok) where
empty = mzero
(<|>) = mplus
instance MonadPlus (Parser tok) where
mzero = Parser $ const Left
Parser p1 `mplus` p2' =
Parser (\s e -> case p1 s e of
Left e' -> runParser p2' s (e' ++ e)
r1 -> r1)
instance TryAlternative (Parser tok)
instance Eq tok => Syntax tok (Parser tok) where
token = Parser (\s e -> case s of
t:ts -> Right (t, ts)
[] -> Left $ errorString "The end of token stream." : e)
runAsParser :: Eq tok => RunAsParser tok a ErrorStack
runAsParser parser s =
do (a, s') <- runParser parser s []
if s' == []
then Right a
else Left [errorString "Not the end of token stream."]