-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathJsonParser.hs
78 lines (60 loc) · 1.96 KB
/
JsonParser.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
module JsonParser where
import Control.Monad
import Control.Applicative
data JsonValue = JsonNull
| JsonBool Bool
| JsonString String
| JsonNumber Int
| JsonArray [JsonValue]
| JsonObject [(String, JsonValue)]
deriving (Show, Eq)
newtype Parser a = Parser
{
runParser :: String -> Maybe (String, a)
}
instance Functor Parser where
fmap f (Parser p) = Parser $ \input -> do
(input', x) <- p input
Just (input', (f x))
instance Applicative Parser where
pure a = Parser $ \input -> Just (input, a)
(Parser f) <*> (Parser g) = Parser $ \input -> do
(input', p) <- (f input)
(input'', a) <- (g input')
Just $ (input'', (p a))
instance Alternative Parser where
empty = Parser $ \_ -> Nothing
(Parser r) <|> (Parser s) = Parser $ \input ->
(r input) <|> (s input)
jsonNull :: String -> Parser JsonValue
jsonNull s = (\_ -> JsonNull) <$> stringP "null"
jsonBool :: String -> Parser JsonValue
jsonBool s = f <$> (stringP "true" <|> stringP "false")
where
f "true" = JsonBool True
f "false" = JsonBool False
f _ = undefined
spanP :: (Char -> Bool) -> Parser String
spanP f = Parser $ \input ->
let (token, rest) = span f input
in Just (rest, token)
notNull :: Parser [a] -> Parser [a]
notNull p = Parser $ \input -> do
(rest, tok) <- runParser p $ input
case null tok of
True -> Nothing
False -> Just (rest, tok)
jsonNumber :: Parser JsonValue
jsonNumber =
f <$> notNull (spanP isDigit)
where f ns = JsonNumber $ read ns
charP :: Char -> Parser Char
charP x = Parser $ \input ->
case input of
a:as
| a == x -> Just (as, x)
| otherwise -> Nothing
stringP :: String -> Parser String
stringP xs = sequenceA $ map charP xs
jsonValue :: String -> Parser JsonValue
jsonValue = jsonNull <|> jsonBool