@@ -18,7 +18,7 @@ sealed interface JsonValue {
18
18
* @return json value or null if parsing fails
19
19
*/
20
20
fun parseJson (input : String ): JsonValue ? =
21
- when (val result = jsonParser (input)) {
21
+ when (val result = json (input)) {
22
22
null -> null
23
23
else -> when (result.second) {
24
24
" " -> result.first
@@ -27,50 +27,63 @@ fun parseJson(input: String): JsonValue? =
27
27
}
28
28
29
29
30
+ /*
31
+ * Implementation of the grammar from https://www.json.org/json-en.html follows.
32
+ *
33
+ * The parsers defined below are given names that follows the grammar but due to Kotlin
34
+ * initialization orders the ordering are not the same.
35
+ *
36
+ * The parsers are declared as toplevel val's to minimize noise on the use site. This makes
37
+ * the parser very readable, and it almost reads as the official grammar.
38
+ *
39
+ * To be able to define some recursive parsers a "lazy" variant of some parsers was needed,
40
+ * in the form of a function that lazily returns the corresponding parser.
41
+ */
42
+
30
43
31
44
/* *
32
45
* Consumes zero or more whitespace characters.
33
46
*/
34
- val ws: Parser <String > = oneOf(
47
+ private val ws: Parser <String > = oneOf(
35
48
s(" \u0020 " ) + _ws (),
36
49
s(" \u000A " ) + _ws (),
37
50
s(" \u000D " ) + _ws (),
38
51
s(" \u0009 " ) + _ws (),
39
52
succeed(" " )
40
53
)
41
54
42
- fun _ws (): Parser <String > = lazy { ws }
55
+ private fun _ws (): Parser <String > = lazy { ws }
43
56
44
57
45
58
/* *
46
59
* Matches a single digit 1 to 9.
47
60
*/
48
- val onenine: Parser <String > =
61
+ private val onenine: Parser <String > =
49
62
match { it in ' 1' .. ' 9' }.map { it.toString() }
50
63
51
64
/* *
52
65
* Matches a single digit 0 to 9.
53
66
*/
54
- val digit: Parser <String > = oneOf(
67
+ private val digit: Parser <String > = oneOf(
55
68
s(" 0" ),
56
69
onenine
57
70
)
58
71
59
72
/* *
60
73
* Matches one or more digits.
61
74
*/
62
- val digits: Parser <String > = oneOf(
75
+ private val digits: Parser <String > = oneOf(
63
76
digit + _digits (),
64
77
digit
65
78
)
66
79
67
- fun _digits () = lazy { digits }
80
+ private fun _digits () = lazy { digits }
68
81
69
82
70
83
/* *
71
84
* Parse an integer that can start with a minus sign.
72
85
*/
73
- val integer: Parser <String > = oneOf(
86
+ private val integer: Parser <String > = oneOf(
74
87
onenine + digits,
75
88
digit,
76
89
s(" -" ) + onenine + digits,
@@ -83,15 +96,15 @@ val integer: Parser<String> = oneOf(
83
96
*
84
97
* If no fraction is found an empty string is produced.
85
98
*/
86
- val fraction: Parser <String > = oneOf(
99
+ private val fraction: Parser <String > = oneOf(
87
100
s(" ." ) + digits,
88
101
succeed(" " )
89
102
)
90
103
91
104
/* *
92
105
* Parse an optional sign. If no sign is found the empty string is produced.
93
106
*/
94
- val sign: Parser <String > = oneOf(
107
+ private val sign: Parser <String > = oneOf(
95
108
s(" +" ),
96
109
s(" -" ),
97
110
succeed(" " )
@@ -100,7 +113,7 @@ val sign: Parser<String> = oneOf(
100
113
/* *
101
114
* Parse an optional exponent. If no exponent is found the empty string is produced.
102
115
*/
103
- val exponent: Parser <String > = oneOf(
116
+ private val exponent: Parser <String > = oneOf(
104
117
s(" E" ) + sign + digits,
105
118
s(" e" ) + sign + digits,
106
119
succeed(" " )
@@ -110,14 +123,14 @@ val exponent: Parser<String> = oneOf(
110
123
/* *
111
124
* Parse a JSON number.
112
125
*/
113
- val number: Parser <String > =
126
+ private val number: Parser <String > =
114
127
integer + fraction + exponent
115
128
116
129
117
130
/* *
118
131
* Parse one hex digit (both lower and upper case allowed)
119
132
*/
120
- val hex: Parser <String > = oneOf(
133
+ private val hex: Parser <String > = oneOf(
121
134
digit,
122
135
match { it in ' A' .. ' F' }.map { it.toString() },
123
136
match { it in ' a' .. ' f' }.map { it.toString() },
@@ -127,7 +140,7 @@ val hex: Parser<String> = oneOf(
127
140
* Parse an escaped value in a JSON string, i.e. a sequence
128
141
* of characters following a backslash (\).
129
142
*/
130
- val escape: Parser <String > = oneOf(
143
+ private val escape: Parser <String > = oneOf(
131
144
s(" \" " ).map { " \" " },
132
145
s(" \\ " ).map { " \\ " },
133
146
s(" /" ).map { " /" },
@@ -144,38 +157,38 @@ val escape: Parser<String> = oneOf(
144
157
/* *
145
158
* Parse one character in a JSON string. The character can be escaped by a backslash (\).
146
159
*/
147
- val character: Parser <String > = oneOf(
160
+ private val character: Parser <String > = oneOf(
148
161
match { it >= ' \u0020 ' && it != ' \" ' && it != ' \\ ' }.map { it.toString() }, // "
149
162
s(" \\ " ).keep(escape)
150
163
)
151
164
152
165
/* *
153
166
* Parse zero or more valid characters in a JSON string.
154
167
*/
155
- val characters: Parser <String > = oneOf(
168
+ private val characters: Parser <String > = oneOf(
156
169
character + _characters (),
157
170
succeed(" " )
158
171
)
159
172
160
- fun _characters () = lazy { characters }
173
+ private fun _characters () = lazy { characters }
161
174
162
175
163
176
/* *
164
177
* Parse a JSON string.
165
178
*/
166
- val string: Parser <String > =
179
+ private val string: Parser <String > =
167
180
s(" \" " ).keep(characters).skip(s(" \" " ))
168
181
169
182
/* *
170
183
* Parse an element. An element is a json value surrounded by whitespace.
171
184
*/
172
- val element: Parser <JsonValue > =
185
+ private val element: Parser <JsonValue > =
173
186
ws.keep(_jsonValue ()).skip(ws)
174
187
175
188
/* *
176
189
* Parse one or more elements separated by comma (,).
177
190
*/
178
- val elements: Parser <List <JsonValue >> = oneOf(
191
+ private val elements: Parser <List <JsonValue >> = oneOf(
179
192
element.skip(s(" ," )).andThen { first ->
180
193
_elements ().map { rest ->
181
194
listOf (first) + rest
@@ -184,12 +197,12 @@ val elements: Parser<List<JsonValue>> = oneOf(
184
197
element.map { listOf (it) },
185
198
)
186
199
187
- fun _elements (): Parser <List <JsonValue >> = lazy { elements }
200
+ private fun _elements (): Parser <List <JsonValue >> = lazy { elements }
188
201
189
202
/* *
190
203
* Parse one member. A member is one key-value pair in a JSON object.
191
204
*/
192
- val member: Parser <Pair <String , JsonValue >> =
205
+ private val member: Parser <Pair <String , JsonValue >> =
193
206
ws.keep(string).skip(ws).skip(s(" :" )).andThen { key ->
194
207
element.map { value ->
195
208
key to value
@@ -199,7 +212,7 @@ val member: Parser<Pair<String, JsonValue>> =
199
212
/* *
200
213
* Parse one or more members separated by a comma (,).
201
214
*/
202
- val members: Parser <List <Pair <String , JsonValue >>> = oneOf(
215
+ private val members: Parser <List <Pair <String , JsonValue >>> = oneOf(
203
216
member.skip(s(" ," )).andThen { first ->
204
217
_members ().map { rest ->
205
218
listOf (first) + rest
@@ -208,40 +221,40 @@ val members: Parser<List<Pair<String, JsonValue>>> = oneOf(
208
221
member.map { listOf (it) }
209
222
)
210
223
211
- fun _members (): Parser <List <Pair <String , JsonValue >>> = members
224
+ private fun _members (): Parser <List <Pair <String , JsonValue >>> = members
212
225
213
226
214
227
/* *
215
228
* Parse a JSON boolean.
216
229
*/
217
- val jsBool: Parser <JsonValue > = oneOf(
230
+ private val jsBool: Parser <JsonValue > = oneOf(
218
231
s(" true" ).map { JsonValue .Bool (true ) },
219
232
s(" false" ).map { JsonValue .Bool (false ) }
220
233
)
221
234
222
235
/* *
223
236
* Parse a JSON null.
224
237
*/
225
- val jsNull: Parser <JsonValue > =
238
+ private val jsNull: Parser <JsonValue > =
226
239
s(" null" ).map { JsonValue .Null }
227
240
228
241
229
242
/* *
230
243
* Parse a JSON number.
231
244
*/
232
- val jsNum: Parser <JsonValue > =
245
+ private val jsNum: Parser <JsonValue > =
233
246
number.map { JsonValue .Num (it.toDouble()) }
234
247
235
248
/* *
236
249
* Parse a JSON string.
237
250
*/
238
- val jsString: Parser <JsonValue > =
251
+ private val jsString: Parser <JsonValue > =
239
252
string.map { JsonValue .Str (it) }
240
253
241
254
/* *
242
255
* Parse a JSON array.
243
256
*/
244
- val jsArray: Parser <JsonValue > = oneOf(
257
+ private val jsArray: Parser <JsonValue > = oneOf(
245
258
s(" [" ).andThen { ws }.andThen { s(" ]" ) }.map { JsonValue .Array (emptyList<JsonValue >()) },
246
259
s(" [" ).keep(_elements ()).skip(s(" ]" )).map { JsonValue .Array (it) },
247
260
)
@@ -250,15 +263,15 @@ val jsArray: Parser<JsonValue> = oneOf(
250
263
/* *
251
264
* Parse a JSON object.
252
265
*/
253
- val jsObject: Parser <JsonValue > = oneOf(
266
+ private val jsObject: Parser <JsonValue > = oneOf(
254
267
s(" {" ).keep(members).skip(s(" }" )).map { JsonValue .Object (it.toMap()) },
255
268
s(" {" ).skip(ws).keep(s(" }" )).map { JsonValue .Object (emptyMap()) },
256
269
)
257
270
258
271
/* *
259
272
* Parse a JSON value.
260
273
*/
261
- val jsonValue: Parser <JsonValue > = oneOf(
274
+ private val jsonValue: Parser <JsonValue > = oneOf(
262
275
jsNull,
263
276
jsBool,
264
277
jsString,
@@ -267,7 +280,7 @@ val jsonValue: Parser<JsonValue> = oneOf(
267
280
jsObject
268
281
)
269
282
270
- fun _jsonValue () = lazy { jsonValue }
283
+ private fun _jsonValue () = lazy { jsonValue }
271
284
272
285
273
- val jsonParser : Parser <JsonValue > = element
286
+ private val json : Parser <JsonValue > = element
0 commit comments