-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathjson.py
39 lines (26 loc) · 1.3 KB
/
json.py
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
import pyparsing as pp
from bench.helpers import json_unescape
def compile():
LBRACE, RBRACE, LBRACK, RBRACK, COLON = map(pp.Suppress, '{}[]:')
value = pp.Forward()
true = pp.Keyword('true').setParseAction(pp.replaceWith(True))
false = pp.Keyword('false').setParseAction(pp.replaceWith(False))
null = pp.Keyword('null').setParseAction(pp.replaceWith(None))
number = (pp.Regex(r'-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][-+]?[0-9]+)?')
.setParseAction(pp.tokenMap(float)))
string = (pp.Regex(r'"([ !#-\[\]-\U0010ffff]+'
r'|\\(?:["\\/bfnrt]|u[0-9A-Fa-f]{4}))*"')
.setParseAction(pp.tokenMap(json_unescape)))
items = pp.delimitedList(value)
array = (pp.Group(LBRACK - pp.Optional(items) + RBRACK)
.setParseAction(lambda t: t.asList()))
member = pp.Group(string + COLON + value)
members = pp.delimitedList(member)
object = (pp.Dict(LBRACE - pp.Optional(members) + RBRACE)
.setParseAction(lambda t: t.asDict()))
value << (object | array | string | number | true | false | null)
json = value('top') + pp.StringEnd()
json.setDefaultWhitespaceChars(' \t\n\r')
json.parseWithTabs()
return lambda s: json.parseString(s)['top']
parse = compile()