@@ -0,0 +1,223 @@
2+ Simple monadic parser module, based heavily on that by
10+import Prelude.Applicative
23+data Parser a = P (String -> Either String (a, String))
25+parse : Parser a -> String -> Either String (a, String)
26+parse (P p) inp = p inp
28+instance Functor Parser where
29+ -- fmap : (a -> b) -> f a -> f b
30+ -- fmap : (a -> b) -> Parser a -> Parser b
31+ -- Given a function (a -> b), and a parser a, make a parser b
32+ fmap f p = P (\inp => case parse p inp of
33+ (Left err) => Left err
34+ -- Apply f to the v that we got from parsing
35+ (Right (v, rest)) => Right ((f v), rest))
38+instance Applicative Parser where
39+ pure v = P (\inp => Right (v, inp))
40+ -- Parse to get the function, then parse to get the first argument
41+ a <$> b = P (\inp => do (f, rest) <- parse a inp
42+ (x, rest') <- parse b rest
45+instance Monad Parser where
46+-- pure v = P (\inp => Right (v,inp))
47+ -- m a -> (a -> m b) -> m b
48+ p >>= f = P (\inp => case parse p inp of
49+ (Left err) => Left err
50+ (Right (v,rest)) => parse (f v) rest)
52+--mplus : Monad m => m a -> m a -> m a
53+mplus : Parser a -> Parser a -> Parser a
54+mplus p q = P (\inp => case parse p inp of
55+ Left msg => parse q inp
56+ Right (v,out) => Right(v,out))
64+failure : String -> Parser a
65+failure msg = P (\inp => Left msg)
68+item = P (\inp => case unpack inp of
69+ [] => Left "Error! Parsing empty list."
70+ (x::xs) => Right (x, pack xs))
78+(|||) : Parser a -> Parser a -> Parser a
86+sat : (Char -> Bool) -> Parser Char
87+sat p = item >>= (\x => if p x then pure x else failure "failed")
89+oneof : List Char -> Parser Char
90+oneof xs = sat (\x => elem x xs)
104+alphanum : Parser Char
105+alphanum = sat isAlphaNum
107+char : Char -> Parser Char
110+helper : List Char -> Parser (List Char)
111+string : String -> Parser String
112+string s = do result <- helper (unpack s)
115+helper [] = pure Prelude.List.Nil
116+helper (x::xs) = do char x
120+many : Parser a -> Parser (List a)
121+many1 : Parser a -> Parser (List a)
124+ pure $ Prelude.List.(::) v vs
128+bool = parseTrue ||| parseFalse
129+ where parseTrue : Parser Bool
130+ parseTrue = do oneof ['T', 't']
133+ parseFalse = do oneof ['F', 'f']
140+many p = many1 p `mplus` pure Prelude.List.Nil
144+ident : Parser String
145+ident = do x <- letter
146+ xs <- many1 alphanum
150+nat = do xs <- many digit
151+ pure (cast (cast xs))
156+ where neg : Parser Int
162+space = do many (sat isSpace)
168+token : Parser a -> Parser a
174+identifier : Parser String
175+identifier = token ident
183+symbol : String -> Parser String
184+symbol xs = token (string xs)
186+strToken : Parser String
187+strToken = fmap pack (token (many1 alphanum))
189+--apply : Parser a -> String -> List (a,String)
190+--apply p = parse (space >>= (\_ => p))
206+factor = do symbol "("
212+term = do f <- factor
220+eval : String -> Maybe Int
221+eval xs = case (parse expr xs) of
222+ Right (n,rest) => if rest == "" then Just n else Nothing