1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
%-------------------------------= --------------------------------------------
\subsection{Deterministic parser}
%-------------------------------= --------------------------------------------
%if codeOnly || showModuleHeader
> module Parser ( Parser, run, satisfy, lit, lits, wrap, nonnull, eof )
> where
>
> import Char ( isSpace )
> import Auxiliaries
> import Monad ( MonadPlus(..), filterM )
%endif
Deterministische Mini-Parser.
%if style == math
%format (MkParser (p)) = p
%format (unParser (p)) = p
%else
> 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)
>
> satisfy :: (tok -> Bool) -> Parser tok tok
> satisfy pred = MkParser (\inp -> case inp of
> a : rest | pred 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)
> mfilter p m = m >>= \a -> if p a then return a else mzero
%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
|