8 import Control.Applicative
9 import Data.Char(isSpace, isAlpha, isAlphaNum)
11 ------------------------------------------------------------
12 -- 1. Parsing repetitions
13 ------------------------------------------------------------
14 sequenceA :: Applicative f => [f a] -> f [a]
15 sequenceA [] = pure []
16 sequenceA (x:xs) = (:) <$> x <*> sequenceA xs
17 -- sequenceA (x:xs) = liftA2 (:) x (sequenceA xs)
19 replicateA :: Applicative f => Int -> f a -> f [a]
20 replicateA n x = sequenceA (replicate n x)
22 zeroOrMore :: Parser a -> Parser [a]
23 zeroOrMore p = oneOrMore p <|> pure []
25 oneOrMore :: Parser a -> Parser [a]
26 oneOrMore p = liftA2 (:) p (zeroOrMore p)
28 ------------------------------------------------------------
30 ------------------------------------------------------------
32 spaces :: Parser String
33 spaces = zeroOrMore (satisfy isSpace)
35 ident :: Parser String
36 ident = liftA2 (:) (satisfy isAlpha) (zeroOrMore (satisfy isAlphaNum))
38 ------------------------------------------------------------
39 -- 3. Parsing S-expressions
40 ------------------------------------------------------------
42 -- An "identifier" is represented as just a String; however, only
43 -- those Strings consisting of a letter followed by any number of
44 -- letters and digits are valid identifiers.
47 -- An "atom" is either an integer value or an identifier.
48 data Atom = N Integer | I Ident
51 -- An S-expression is either an atom, or a list of S-expressions.
56 parseAtom :: Parser Atom
57 parseAtom = spaces *> (N <$> posInt <|>
58 I <$> ident) <* spaces
60 parseSExpr :: Parser SExpr
61 parseSExpr = A <$> parseAtom <|>
64 parseComb = spaces *> char '(' *> oneOrMore parseSExpr <* spaces <* char ')' <* spaces