-
Notifications
You must be signed in to change notification settings - Fork 5
/
json.py
56 lines (49 loc) · 1.66 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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import pe
from pe.actions import Constant, Pack, Capture
from bench.helpers import json_unescape
def compile():
Json = pe.compile(
r'''
# Syntactic rules
Start <- Spacing Value EOF
Value <- Object / Array / String / Number / Constant
Object <- LBRACE (Member (COMMA Member)*)? RBRACE
Member <- String COLON Value
Array <- LBRACK (Value (COMMA Value)*)? RBRACK
String <- ["] CHAR* ( ESC CHAR* )* ["]
Number <- INTEGER FRACTION? EXPONENT?
Constant <- TRUE / FALSE / NULL
# Lexical rules
CHAR <- [ !#-\[\]-\U0010ffff]
ESC <- '\\' ( ["\\/bfnrt]
/ 'u' HEX HEX HEX HEX )
HEX <- [0-9a-fA-F]
INTEGER <- "-"? ("0" / [1-9] [0-9]*)
FRACTION <- "." [0-9]+
EXPONENT <- [eE] [-+]? [0-9]+
TRUE <- "true"
FALSE <- "false"
NULL <- "null"
LBRACE <- "{" Spacing
RBRACE <- Spacing "}"
LBRACK <- "[" Spacing
RBRACK <- Spacing "]"
COMMA <- Spacing "," Spacing
COLON <- Spacing ":" Spacing
Spacing <- [\t\n\r ]*
EOF <- Spacing !.
''',
actions = {
'Object': Pack(dict),
'Member': Pack(tuple),
'Array': Pack(list),
'String': Capture(json_unescape),
'Number': Capture(float),
'TRUE': Constant(True),
'FALSE': Constant(False),
'NULL': Constant(None),
},
parser='machine',
flags=pe.OPTIMIZE)
return lambda s: Json.match(s, flags=pe.STRICT).value()
parse = compile()