-
Notifications
You must be signed in to change notification settings - Fork 0
/
json.peg
127 lines (98 loc) · 2.02 KB
/
json.peg
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
%%
String _escape(int charCode) {
switch (charCode) {
case 0x22:
return '"';
case 0x2f:
return '/';
case 0x5c:
return '\\';
case 0x62:
return '\b';
case 0x66:
return '\f';
case 0x6e:
return '\n';
case 0x72:
return '\r';
case 0x74:
return '\t';
default:
throw StateError('Unable to escape charCode: $charCode');
}
}
%%
@event
Start = Spaces v:Value @eof() ;
@event
Array = OpenBracket ↑ v:Values CloseBracket ;
@inline
CloseBrace = v:'}' Spaces ;
@inline
CloseBracket = v:']' Spaces ;
@inline
Colon = v:':' Spaces ;
@inline
Comma = v:',' Spaces ;
String
EscapeChar = c:["/bfnrt\\] { $$ = _escape(c); } ;
String
EscapeHex = 'u' v:HexNumber { $$ = String.fromCharCode(v); } ;
HexNumber = @indicate('Expected 4 digit hex number', HexNumber_) ;
@inline
int
HexNumber_ = v:$[0-9A-Fa-f]{4} { $$ = int.parse(v, radix: 16); } ;
@inline
bool
False = 'false' Spaces { $$ = false; } ;
@inline
@event
Key = String ;
@event
MapEntry<String, Object?>
KeyValue = k:Key Colon ↑ v:Value { $$ = MapEntry(k, v); };
KeyValues = @list(KeyValue, Comma ↑ v:KeyValue);
@inline
Object?
Null = 'null' Spaces { $$ = null; } ;
@inline
num
Number_ = v:$(
[-]?
([0] / [1-9][0-9]*)
([.] ↑ [0-9]+)?
([eE] ↑ [-+]? [0-9]+)?
) { $$ = num.parse(v); } ;
num
Number = v:@expected('number', Number_) Spaces ;
@event
Map<String, Object?>
Object = OpenBrace ↑ kv:KeyValues CloseBrace { $$ = kv.isEmpty ? const {} : Map.fromEntries(kv); };
@inline
OpenBrace = v:'{' Spaces ;
@inline
OpenBracket = v:'[' Spaces ;
@inline
Quote = v:'"' Spaces ;
Spaces = [ \n\r\t]* ;
@inline
StringChars = @stringChars(
$[\u{20}-\u{21}\u{23}-\u{5b}\u{5d}-\u{10ffff}]+,
[\\],
(EscapeChar / EscapeHex)
) ;
String
String = '"' ↑ v:StringChars Quote ;
@inline
bool
True = 'true' Spaces { $$ = true; } ;
@event
Value =
String
/ Object
/ Array
/ Number
/ True
/ False
/ Null ;
Values = @list(Value, Comma ↑ v:Value) ;