SHOW:
|
|
- or go back to the newest paste.
1 | {- CIS 194 HW 11 | |
2 | due Monday, 8 April | |
3 | -} | |
4 | ||
5 | module Week11.SExpr where | |
6 | ||
7 | import Week11.AParser | |
8 | import Control.Applicative | |
9 | ||
10 | import Data.Char(isSpace, isAlpha, isAlphaNum) | |
11 | ||
12 | ------------------------------------------------------------ | |
13 | -- 1. Parsing repetitions | |
14 | ------------------------------------------------------------ | |
15 | ||
16 | zeroOrMore :: Parser a -> Parser [a] | |
17 | zeroOrMore p = many_v | |
18 | where many_v = some_v <|> pure [] | |
19 | some_v = (:) <$> p <*> many_v | |
20 | ||
21 | oneOrMore :: Parser a -> Parser [a] | |
22 | oneOrMore p = some_v | |
23 | where many_v = some_v <|> pure [] | |
24 | some_v = (:) <$> p <*> many_v | |
25 | ||
26 | ------------------------------------------------------------ | |
27 | -- 2. Utilities | |
28 | ------------------------------------------------------------ | |
29 | ||
30 | spaces :: Parser String | |
31 | spaces = zeroOrMore (satisfy isSpace) | |
32 | ||
33 | ident :: Parser String | |
34 | ident = (:) <$> satisfy isAlpha <*> zeroOrMore (satisfy isAlphaNum) | |
35 | ||
36 | ------------------------------------------------------------ | |
37 | -- 3. Parsing S-expressions | |
38 | ------------------------------------------------------------ | |
39 | ||
40 | -- An "identifier" is represented as just a String; however, only | |
41 | -- those Strings consisting of a letter followed by any number of | |
42 | -- letters and digits are valid identifiers. | |
43 | type Ident = String | |
44 | ||
45 | -- An "atom" is either an integer value or an identifier. | |
46 | data Atom = N Integer | I Ident | |
47 | deriving Show | |
48 | ||
49 | -- An S-expression is either an atom, or a list of S-expressions. | |
50 | data SExpr = A Atom | |
51 | | Comb [SExpr] | |
52 | deriving Show | |
53 | ||
54 | parseAtom :: Parser Atom | |
55 | parseAtom = ( N <$> (spaces *> posInt)) <|> ( I <$> (spaces *> ident)) | |
56 | ||
57 | ||
58 | parseSExpr :: Parser SExpr | |
59 | parseSExpr = (A <$> parseAtom) <|> Comb <$> (spaces *> char '(' *> oneOrMore (parseSExpr) <* spaces <* char ')') |