File tree Expand file tree Collapse file tree 1 file changed +124
-0
lines changed
Expand file tree Collapse file tree 1 file changed +124
-0
lines changed Original file line number Diff line number Diff line change 1+ import Control.Applicative
2+ import Data.Char
3+
4+ newtype Parser a = P (String -> [(a , String )])
5+
6+ parse :: Parser a -> String -> [(a , String )]
7+ parse (P p) inp = p inp
8+
9+ item :: Parser Char
10+ item = P $ \ inp ->
11+ case inp of
12+ [] -> []
13+ (x: xs) -> [(x, xs)]
14+
15+ instance Functor Parser where
16+ fmap f p = P $ \ inp ->
17+ case parse p inp of
18+ [] -> []
19+ [(v, out)] -> [(f v, out)]
20+
21+ instance Applicative Parser where
22+ pure v = P $ \ inp -> [(v, inp)]
23+
24+ pf <*> px = P $ \ inp ->
25+ case parse pf inp of
26+ [] -> []
27+ [(f, out)] -> parse (fmap f px) out
28+
29+ instance Monad Parser where
30+ p >>= f = P $ \ inp ->
31+ case parse p inp of
32+ [] -> []
33+ [(v, out)] -> parse (f v) out
34+
35+ instance Alternative Parser where
36+ empty = P $ \ inp -> []
37+
38+ p <|> q = P $ \ inp ->
39+ case parse p inp of
40+ [] -> parse q inp
41+ [(v, out)] -> [(v, out)]
42+
43+ sat :: (Char -> Bool ) -> Parser Char
44+ sat p = do
45+ x <- item
46+ if p x
47+ then return x
48+ else empty
49+
50+ digit :: Parser Char
51+ digit = sat isDigit
52+
53+ lower :: Parser Char
54+ lower = sat isLower
55+
56+ upper :: Parser Char
57+ upper = sat isUpper
58+
59+ letter :: Parser Char
60+ letter = sat isAlpha
61+
62+ alphanum :: Parser Char
63+ alphanum = sat isAlphaNum
64+
65+ char :: Char -> Parser Char
66+ char x = sat (== x)
67+
68+ string :: String -> Parser String
69+ string [] = return []
70+ string (x: xs) = do
71+ char x
72+ string xs
73+ return (x: xs)
74+
75+ ident :: Parser String
76+ ident = do
77+ x <- lower
78+ xs <- many alphanum
79+ return (x: xs)
80+
81+ nat :: Parser Int
82+ nat = do
83+ xs <- some digit
84+ return (read xs)
85+
86+ space :: Parser ()
87+ space = do
88+ many (sat isSpace)
89+ return ()
90+
91+ int :: Parser Int
92+ int = do
93+ char ' -'
94+ n <- nat
95+ return (- n) <|> nat
96+
97+ token :: Parser a -> Parser a
98+ token p = do
99+ space
100+ v <- p
101+ space
102+ return v
103+
104+ identifier :: Parser String
105+ identifier = token ident
106+
107+ natural :: Parser Int
108+ natural = token nat
109+
110+ integer :: Parser Int
111+ integer = token int
112+
113+ symbol :: String -> Parser String
114+ symbol xs = token (string xs)
115+
116+ nats :: Parser [Int ]
117+ nats = do
118+ symbol " ["
119+ n <- natural
120+ ns <- many $ do
121+ symbol " ,"
122+ natural
123+ symbol " ]"
124+ return (n: ns)
You can’t perform that action at this time.
0 commit comments