-
Notifications
You must be signed in to change notification settings - Fork 1
/
JSONParser.hs
66 lines (58 loc) · 1.64 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
jsonString :: Parser Chars
jsonString =
between
(is $ fromSpecialCharacter DoubleQuote)
(charTok $ fromSpecialCharacter DoubleQuote)
(list (spacialHex <|> noneof (listh "\\\"")))
where
spacialHex = is '\\' *> (hexu ||| special)
special =
do
c <- character
case toSpecialCharacter c of
Full sc -> valueParser
$ fromSpecialCharacter sc
Empty -> unexpectedCharParser c
jsonNumber :: Parser Rational
jsonNumber = P $ \inp ->
case readFloats inp of
Full (num, inp') -> Result inp' num
Empty -> ErrorResult $
case inp of
Nil -> UnexpectedEof
c :. _ -> UnexpectedChar c
jsonTrue :: Parser Chars
jsonTrue = stringTok "true"
jsonFalse :: Parser Chars
jsonFalse = stringTok "false"
jsonNull :: Parser Chars
jsonNull = stringTok "null"
jsonArray :: Parser (List JsonValue)
jsonArray = betweenSepbyComma '[' ']' jsonValue
jsonObject :: Parser Assoc
jsonObject = betweenSepbyComma '{' '}' singleObject
where
singleObject =
do
spaces
s <- jsonString
spaces
is ':'
v <- jsonValue
spaces
return (s, v)
jsonValue :: Parser JsonValue
jsonValue = spaces *> (
(pure JsonNull <* jsonNull) <|>
(pure JsonTrue <* jsonTrue) <|>
(pure JsonFalse <* jsonFalse) <|>
(JsonArray <$> jsonArray) <|>
(JsonString <$> jsonString) <|>
(JsonObject <$> jsonObject) <|>
(JsonRational False <$> jsonNumber)
) <* spaces
readJsonValue :: Filename -> IO (ParseResult JsonValue)
readJsonValue filename =
do
inp <- readFile filename
return (parse jsonValue inp)