Skip to content

Commit 7b71f8f

Browse files
committed
Add parsing sequence for lists of natural numbers
1 parent 69d73f9 commit 7b71f8f

File tree

1 file changed

+124
-0
lines changed

1 file changed

+124
-0
lines changed
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
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)

0 commit comments

Comments
 (0)