2 Simple monadic parser module, based heavily on that by
10import Prelude.Applicative
17--------------------------------------------------------------------------------
18-- The monad of parsers
19--------------------------------------------------------------------------------
21data Parser a = P (String -> Either String (a, String))
23parse : Parser a -> String -> Either String (a, String)
24parse (P p) inp = p inp
26instance Functor Parser where
27 map f p = P (\inp => case parse p inp of
29 Right (v, rest) => Right ((f v), rest))
31instance Applicative Parser where
32 pure v = P (\inp => Right (v, inp))
33 a <$> b = P (\inp => do (f, rest) <- parse a inp
34 (x, rest') <- parse b rest
37instance Monad Parser where
38 p >>= f = P (\inp => case parse p inp of
40 Right (v,rest) => parse (f v) rest)
42instance Alternative Parser where
43 empty = P (const (Left "empty"))
44 p <|> q = P (\inp => case parse p inp of
45 Left msg => parse q inp
46 Right (v,out) => Right (v,out))
49--------------------------------------------------------------------------------
51--------------------------------------------------------------------------------
53failure : String -> Parser a
54failure msg = P (\inp => Left msg)
57item = P (\inp => case choose (inp == "") of
58 Left _ => Left "Error! Parsing empty list."
59 Right p => Right (strHead' inp p, strTail' inp p))
62--------------------------------------------------------------------------------
64--------------------------------------------------------------------------------
66sat : (Char -> Bool) -> Parser Char
71oneof : List Char -> Parser Char
72oneof xs = sat (\x => elem x xs)
87alphanum = sat isAlphaNum
89char : Char -> Parser Char
92string : String -> Parser String
93string s = map pack (traverse char (unpack s))
96 many1 : Parser a -> Parser (List a)
97 many1 p = [| p :: many p |]
99 many : Parser a -> Parser (List a)
100 many p = lazy (many1 p) <|> pure []
103bool = parseTrue <|> parseFalse
104 where parseTrue : Parser Bool
105 parseTrue = do oneof ['T', 't']
108 parseFalse = do oneof ['F', 'f']
114 where xs : Parser (List Char)
115 xs = [| letter :: many1 alphanum |]
118nat = do xs <- many digit
119 pure (cast (cast xs))
123 where neg : Parser Int
129space = do many (sat isSpace)
133--------------------------------------------------------------------------------
135--------------------------------------------------------------------------------
137token : Parser a -> Parser a
138token p = space $> p <$ space
140identifier : Parser String
141identifier = token ident
149symbol : String -> Parser String
150symbol xs = token (string xs)
152strToken : Parser String
153strToken = map pack (token (many1 alphanum))
155--------------------------------------------------------------------------------
157--------------------------------------------------------------------------------
159optional : Parser a -> Parser (Maybe a)
160optional p = map Just p <|> pure Nothing
162sepBy1 : Parser a -> Parser b -> Parser (List a)
163sepBy1 p s = [| p :: many (s $> p) |]
165sepBy : Parser a -> Parser b -> Parser (List a)
166sepBy p s = sepBy1 p s <|> pure Nil
168manyTil : Parser a -> Parser b -> Parser (List a)
169manyTil p e = (e $> pure Nil) <|> lazy [| p :: manyTil p e |] <|> pure Nil
171--------------------------------------------------------------------------------
173--------------------------------------------------------------------------------
180 map (t+) (symbol "+" $> expr) <|> pure t
182factor = (symbol "(" $> expr <$ symbol ")") <|> natural
185 map (f*) (symbol "*" $> term) <|> pure f
187eval : String -> Maybe Int
188eval xs = case (parse expr xs) of
189 Right (n,rest) => if rest == "" then Just n else Nothing
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list