%-------------------------------= -------------------------------------------- \subsection{Deterministic parser} %-------------------------------= -------------------------------------------- %if codeOnly || showModuleHeader > module Parser ( Parser, run, satisfy, lit, lits, wrap, nonnull, eof ) > where > > import Control.Applicative > import Control.Monad ( MonadPlus(..), ap, mfilter ) %endif Deterministische Mini-Parser. %if style == math %format (MkParser (p)) = p %format (unParser (p)) = p %else > unParser :: Parser tok a -> [tok] -> Maybe (a, [tok]) > unParser (MkParser p) = p %endif > newtype Parser tok a = MkParser ([tok] -> Maybe (a, [tok])) > > run :: Parser tok a -> [tok] -> Maybe a > run (MkParser p) inp = fmap fst (p inp) > > instance Functor (Parser tok) where > fmap f m = m >>= \a -> return (f a) > instance Monad (Parser tok) where > return a = MkParser (\inp -> Just (a, inp)) > m >>= k = MkParser (\inp -> case unParser m inp of > Nothing -> Nothing > Just (a, rest) -> unParser (k a) rest) > instance MonadPlus (Parser tok) where > mzero = MkParser (\_inp -> Nothing) > m `mplus` n = MkParser (\inp -> unParser m inp `mplus` unParser n inp) > instance Applicative (Parser tok) where > pure = return > (<*>) = ap > instance Alternative (Parser tok) where > empty = mzero > (<|>) = mplus > > satisfy :: (tok -> Bool) -> Parser tok tok > satisfy p = MkParser (\inp -> case inp of > a : rest | p a -> Just (a, rest) > _ -> Nothing) > > lit :: (Eq tok) => tok -> Parser tok tok > lit c = satisfy (== c) ks, 06.09.2003: Adding eof that accepts succeeds only at the end of input. > eof :: Parser tok () > eof = MkParser (\inp -> case inp of > [] -> Just ((),[]) > _ -> Nothing) |lits s| corresponds to |mapM_ lit_ s|. > lits :: (Eq tok) => [tok] -> Parser tok () > lits s = MkParser (\inp -> case splitAt (length s) inp of > (s', rest) | s == s' -> Just ((), rest) > _ -> Nothing) \Todo{Better name for |wrap|.} > wrap :: ([tok] -> (a, [tok])) -> Parser tok a > wrap f = MkParser (\inp -> Just (f inp)) > > nonnull :: ([tok] -> ([a], [tok])) -> Parser tok [a] > nonnull f = mfilter (not . null) (wrap f) %if False > {- > lit_ :: (Eq tok) => tok -> Parser tok () > lit_ c = MkParser (\inp -> case inp of > c' : rest | c == c' -> Just ((), rest) > _ -> Nothing) > nonnull_ f = MkParser (\inp -> case f inp of > res@((_ : _) ,_) -> Just res > _ -> Nothing) > -} %endif