content: %-------------------------------=  --------------------------------------------
  \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                    =  pure
  >     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 a                    =  MkParser (\inp -> Just (a, inp))
  >     (<*>)                     =  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
  