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']
113ident = map pack [| letter :: many1 alphanum |]
116nat = do xs <- many digit
117 pure (cast (cast xs))
121 where neg : Parser Int
127space = do many (sat isSpace)
131--------------------------------------------------------------------------------
133--------------------------------------------------------------------------------
135token : Parser a -> Parser a
136token p = space $> p <$ space
138identifier : Parser String
139identifier = token ident
147symbol : String -> Parser String
148symbol xs = token (string xs)
150strToken : Parser String
151strToken = map pack (token (many1 alphanum))
153--------------------------------------------------------------------------------
155--------------------------------------------------------------------------------
157optional : Parser a -> Parser (Maybe a)
158optional p = map Just p <|> pure Nothing
160sepBy1 : Parser a -> Parser b -> Parser (List a)
161sepBy1 p s = [| p :: many (s $> p) |]
163sepBy : Parser a -> Parser b -> Parser (List a)
164sepBy p s = sepBy1 p s <|> pure Nil
166manyTil : Parser a -> Parser b -> Parser (List a)
167manyTil p e = (e $> pure Nil) <|> lazy [| p :: manyTil p e |] <|> pure Nil
169--------------------------------------------------------------------------------
171--------------------------------------------------------------------------------
178 map (t+) (symbol "+" $> expr) <|> pure t
180factor = (symbol "(" $> expr <$ symbol ")") <|> natural
183 map (f*) (symbol "*" $> term) <|> pure f
185eval : String -> Maybe Int
186eval xs = case (parse expr xs) of
187 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