Skip to content

Commit fb414d9

Browse files
committed
move json parser, don't delete it
1 parent 64f7cbc commit fb414d9

2 files changed

Lines changed: 144 additions & 0 deletions

File tree

pixie/parser/json.pxi

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
(ns pixie.parser.json
2+
(:require [pixie.parser :refer :all]
3+
[pixie.stdlib :as std]))
4+
5+
6+
7+
;; Basic numeric parser. Supports integers (1, 2, 43), decimals (0.1, 1.1, 1000.11) and exponents (1e42, 1E-2)
8+
(defparser NumberParser []
9+
NUMBER (and (maybe \-)
10+
-> sign
11+
12+
(or (and
13+
(parse-if (set "123456789")) -> first
14+
(zero+chars digits) -> rest
15+
<- (str first rest))
16+
(and \0 <- "0"))
17+
-> integer-digits
18+
19+
(maybe (and \.
20+
(one+chars digits) -> digits
21+
<- digits))
22+
-> fraction-digits
23+
24+
25+
(maybe (and (parse-if (set "eE"))
26+
(maybe (parse-if (set "-+"))) -> exp-sign
27+
(one+chars digits) -> exp-digits
28+
<- [(std/or exp-sign "") exp-digits]))
29+
-> exp-data
30+
31+
<- (std/read-string (str (std/or sign "")
32+
integer-digits
33+
(if fraction-digits (str "." fraction-digits) "")
34+
(if exp-data (apply str "E" exp-data) "")))))
35+
36+
(def valid-escape-chars
37+
{\\ \\
38+
\" \"
39+
\/ \/
40+
\b \backspace
41+
\f \formfeed
42+
\n \newline
43+
\r \return
44+
\t \tab})
45+
46+
47+
;; Defines a JSON escaped string parser. Supports all the normal \n \f \r stuff as well
48+
;; as \uXXXX unicode characters
49+
(defparser EscapedStringParser []
50+
CHAR (or (and \\
51+
(one-of valid-escape-chars) -> char
52+
<- (valid-escape-chars char))
53+
54+
(and \\
55+
\u
56+
digits -> d1
57+
digits -> d2
58+
digits -> d3
59+
digits -> d4
60+
<- (char (std/read-string (str "0x" d1 d2 d3 d4))))
61+
62+
(parse-if #(not= % \")))
63+
64+
STRING (and \"
65+
(zero+chars CHAR) -> s
66+
\"
67+
<- s))
68+
69+
;; Basic JSON parser
70+
(defparser JSONParser [NumberParser EscapedStringParser]
71+
72+
NULL (sequence "null" <- nil)
73+
TRUE (sequence "true" <- true)
74+
FALSE (sequence "false" <- false)
75+
ARRAY (and \[
76+
(eat whitespace)
77+
(zero+ (and ENTRY -> e
78+
(maybe \,)
79+
<- e)) -> items
80+
(eat whitespace)
81+
(eat whitespace)
82+
\]
83+
<- items)
84+
MAP-ENTRY (and (eat whitespace)
85+
STRING -> key
86+
(eat whitespace)
87+
\:
88+
ENTRY -> value
89+
(maybe \,)
90+
<- [key value])
91+
MAP (and \{
92+
(zero+ MAP-ENTRY) -> items
93+
(eat whitespace)
94+
\}
95+
<- (apply hashmap (apply concat items)))
96+
ENTRY (and
97+
(eat whitespace)
98+
(or NUMBER MAP STRING NULL TRUE FALSE ARRAY) -> val
99+
(eat whitespace)
100+
<- val)
101+
ENTRY-AT-END (and ENTRY -> e
102+
(eat whitespace)
103+
end
104+
<- e))
105+
106+
(defn read-string [s]
107+
(let [c (string-cursor s)
108+
result ((:ENTRY-AT-END JSONParser) c)]
109+
(if (failure? result)
110+
(println (current c) (snapshot c))
111+
result)))
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
(ns pixie.tests.parser.test-json
2+
(:require [pixie.test :refer :all]
3+
[pixie.parser.json :as json]))
4+
5+
6+
7+
(deftest test-json-numbers
8+
(assert-table [x y] (assert= (json/read-string x) y)
9+
"1" 1
10+
"1.0" 1.0
11+
"0.1" 0.1
12+
"1.1" 1.1
13+
"1234.5678" 1234.5678
14+
15+
"-1" -1
16+
"-0.1" -0.1
17+
"-1.1" -1.1
18+
"-1234.5678" -1234.5678
19+
"1e1" 1e1))
20+
21+
(deftest test-vectors
22+
(assert-table [x y] (assert= (json/read-string x) y)
23+
"[]" []
24+
"[null]" [nil]
25+
"[1, 2]" [1 2]
26+
"[1, 1.0, null]" [1 1.0 nil]
27+
"[\"foo\", 42]" ["foo" 42]))
28+
29+
(deftest test-maps
30+
(assert-table [x y] (assert= (json/read-string x) y)
31+
"{\"foo\": 42}" {"foo", 42}
32+
"{\"foo\": 42, \"bar\":null}" {"foo" 42
33+
"bar" nil}))

0 commit comments

Comments
 (0)