json5-ruby 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/NOTICE +6 -0
- data/README.md +161 -0
- data/SECURITY.md +9 -0
- data/docs/conformance-matrix.md +90 -0
- data/docs/conformance-report.md +29 -0
- data/grammar/json5.y +74 -0
- data/lib/json5/ascii_classification.rb +31 -0
- data/lib/json5/diagnostic.rb +70 -0
- data/lib/json5/document.rb +20 -0
- data/lib/json5/document_nodes.rb +99 -0
- data/lib/json5/document_parser.rb +291 -0
- data/lib/json5/ecma_string.rb +106 -0
- data/lib/json5/errors.rb +67 -0
- data/lib/json5/generated_parser.ibex.json +196 -0
- data/lib/json5/generated_parser.rb +10066 -0
- data/lib/json5/input.rb +283 -0
- data/lib/json5/lexer.rb +599 -0
- data/lib/json5/limits.rb +47 -0
- data/lib/json5/line_map.rb +92 -0
- data/lib/json5/number_value.rb +119 -0
- data/lib/json5/object_value.rb +28 -0
- data/lib/json5/parser.rb +301 -0
- data/lib/json5/public_token_names.rb +43 -0
- data/lib/json5/ruby_value_builder.rb +236 -0
- data/lib/json5/token.rb +26 -0
- data/lib/json5/unicode_tables.rb +42 -0
- data/lib/json5/version.rb +7 -0
- data/lib/json5.rb +47 -0
- data/tool/sources.yml +21 -0
- data/tool/unicode/README.md +19 -0
- data/tool/unicode/UNICODE-LICENSE.txt +39 -0
- data/tool/unicode/checksums.txt +1 -0
- metadata +91 -0
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JSON5
|
|
4
|
+
class RubyValueBuilder
|
|
5
|
+
VALID_DUPLICATE_POLICIES = %i[last first error preserve].freeze
|
|
6
|
+
VALID_NUMBER_MODES = %i[native float lexeme].freeze
|
|
7
|
+
VALID_STRING_MODES = %i[ruby code_units].freeze
|
|
8
|
+
|
|
9
|
+
def initialize(number_mode: :native, string_mode: :ruby, lone_surrogate: :error,
|
|
10
|
+
duplicate_keys: :last, limits: Limits.default, diagnostics: nil,
|
|
11
|
+
warn_duplicate_keys: false, freeze_values: false, source: nil, filename: nil)
|
|
12
|
+
validate_option!(VALID_NUMBER_MODES, number_mode, :number_mode)
|
|
13
|
+
validate_option!(VALID_STRING_MODES, string_mode, :string_mode)
|
|
14
|
+
validate_option!(%i[error replace], lone_surrogate, :lone_surrogate)
|
|
15
|
+
validate_option!(VALID_DUPLICATE_POLICIES, duplicate_keys, :duplicate_keys)
|
|
16
|
+
unless warn_duplicate_keys == true || warn_duplicate_keys == false
|
|
17
|
+
raise ArgumentError, "warn_duplicate_keys must be true or false"
|
|
18
|
+
end
|
|
19
|
+
@number_mode = number_mode
|
|
20
|
+
@string_mode = string_mode
|
|
21
|
+
@lone_surrogate = lone_surrogate
|
|
22
|
+
@duplicate_keys = duplicate_keys
|
|
23
|
+
@limits = limits
|
|
24
|
+
@diagnostics = DiagnosticSink.build(diagnostics, filename: filename)
|
|
25
|
+
@warn_duplicate_keys = warn_duplicate_keys
|
|
26
|
+
@freeze_values = freeze_values
|
|
27
|
+
@source = source
|
|
28
|
+
@filename = filename
|
|
29
|
+
@value_tokens = {}
|
|
30
|
+
@key_tokens = {}
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def observe_token(token)
|
|
34
|
+
@last_token = token
|
|
35
|
+
value = token.value
|
|
36
|
+
@value_tokens[value.object_id] = token if value
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def retain_punctuation_tokens?
|
|
40
|
+
false
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def string(value)
|
|
44
|
+
token = take_value_token(value)
|
|
45
|
+
result = case @string_mode
|
|
46
|
+
when :code_units
|
|
47
|
+
value
|
|
48
|
+
else
|
|
49
|
+
emit_lone_surrogate_warning(value, token) if @lone_surrogate == :replace
|
|
50
|
+
value.to_utf8(lone_surrogate: @lone_surrogate)
|
|
51
|
+
end
|
|
52
|
+
@freeze_values ? result.freeze : result
|
|
53
|
+
rescue ConversionError => error
|
|
54
|
+
raise contextual_error(error, token)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def number(value)
|
|
58
|
+
token = take_value_token(value)
|
|
59
|
+
number_value = value.is_a?(NumberValue) ? value : NumberValue.new(value)
|
|
60
|
+
result = case @number_mode
|
|
61
|
+
when :lexeme
|
|
62
|
+
number_value
|
|
63
|
+
when :float
|
|
64
|
+
convert_float(number_value)
|
|
65
|
+
else
|
|
66
|
+
number_value.to_native
|
|
67
|
+
end
|
|
68
|
+
@freeze_values ? result.freeze : result
|
|
69
|
+
rescue JSON5::Error => error
|
|
70
|
+
raise contextual_error(error, token)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def literal(value, result)
|
|
74
|
+
take_value_token(value)
|
|
75
|
+
result
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def member_name(value)
|
|
79
|
+
token = take_value_token(value)
|
|
80
|
+
if @string_mode == :code_units
|
|
81
|
+
key = value.is_a?(ECMAString) ? value : ECMAString.new(value.raw.codepoints)
|
|
82
|
+
remember_key(key, token)
|
|
83
|
+
return key
|
|
84
|
+
end
|
|
85
|
+
raw = value.is_a?(NumberValue) ? value.raw : value
|
|
86
|
+
if raw.is_a?(String)
|
|
87
|
+
key = raw.to_s.dup.freeze
|
|
88
|
+
remember_key(key, token)
|
|
89
|
+
return key
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
begin
|
|
93
|
+
key = value.to_utf8(lone_surrogate: :error).freeze
|
|
94
|
+
remember_key(key, token)
|
|
95
|
+
key
|
|
96
|
+
rescue ConversionError => error
|
|
97
|
+
if @duplicate_keys == :preserve
|
|
98
|
+
remember_key(value, token)
|
|
99
|
+
return value
|
|
100
|
+
end
|
|
101
|
+
raise contextual_error(ConversionError.new(
|
|
102
|
+
"lone surrogate cannot be used as a Ruby Hash key",
|
|
103
|
+
code: "lone_surrogate_key"
|
|
104
|
+
), token)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def object(members, *_punctuation)
|
|
109
|
+
enforce_entry_limit(members.length)
|
|
110
|
+
if @duplicate_keys == :preserve
|
|
111
|
+
members.each { |key, _value| @key_tokens.delete(key.object_id) }
|
|
112
|
+
return ObjectValue.new(members)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
result = {}
|
|
116
|
+
members.each do |key, value|
|
|
117
|
+
token = @key_tokens.delete(key.object_id)
|
|
118
|
+
if result.key?(key)
|
|
119
|
+
emit_duplicate_key_warning(token) if @warn_duplicate_keys && %i[last first].include?(@duplicate_keys)
|
|
120
|
+
case @duplicate_keys
|
|
121
|
+
when :first
|
|
122
|
+
next
|
|
123
|
+
when :error
|
|
124
|
+
raise contextual_error(DuplicateKeyError.new("duplicate object member name", code: "duplicate_key"), token)
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
result[key] = value
|
|
128
|
+
end
|
|
129
|
+
@freeze_values ? result.freeze : result
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def member(name, _colon, value)
|
|
133
|
+
[name, value]
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def member_list(member)
|
|
137
|
+
enforce_entry_limit(1)
|
|
138
|
+
[member]
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def append_member(members, member, _comma = nil)
|
|
142
|
+
enforce_entry_limit(members.length + 1)
|
|
143
|
+
members << member
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def array(values, *_punctuation)
|
|
147
|
+
enforce_entry_limit(values.length)
|
|
148
|
+
result = values
|
|
149
|
+
@freeze_values ? result.freeze : result
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def element_list(element)
|
|
153
|
+
enforce_entry_limit(1)
|
|
154
|
+
[element]
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def append_element(elements, element, _comma = nil)
|
|
158
|
+
enforce_entry_limit(elements.length + 1)
|
|
159
|
+
elements << element
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
private
|
|
163
|
+
|
|
164
|
+
def convert_float(value)
|
|
165
|
+
result = value.to_f
|
|
166
|
+
return -0.0 if value.raw.start_with?("-") && result.zero?
|
|
167
|
+
result
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def enforce_entry_limit(count)
|
|
171
|
+
return unless @limits.max_container_entries && count > @limits.max_container_entries
|
|
172
|
+
raise contextual_error(
|
|
173
|
+
LimitError.new("container exceeds max_container_entries", code: "maximum_container_entries_exceeded"),
|
|
174
|
+
@last_token
|
|
175
|
+
)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def validate_option!(allowed, value, name)
|
|
179
|
+
return if allowed.include?(value)
|
|
180
|
+
raise ArgumentError, "#{name} must be one of #{allowed.inspect}"
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def emit_lone_surrogate_warning(value, token)
|
|
184
|
+
return unless value.lone_surrogate?
|
|
185
|
+
|
|
186
|
+
@diagnostics.emit(
|
|
187
|
+
code: "lone_surrogate_replaced",
|
|
188
|
+
message: "lone surrogate was replaced with U+FFFD",
|
|
189
|
+
byte_offset: token&.start_byte || 0,
|
|
190
|
+
end_byte_offset: token&.end_byte || 0,
|
|
191
|
+
line: token&.line,
|
|
192
|
+
column: token&.column
|
|
193
|
+
)
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def emit_duplicate_key_warning(token)
|
|
197
|
+
@diagnostics.emit(
|
|
198
|
+
code: "duplicate_key",
|
|
199
|
+
message: "duplicate object member name",
|
|
200
|
+
byte_offset: token&.start_byte || 0,
|
|
201
|
+
end_byte_offset: token&.end_byte || 0,
|
|
202
|
+
line: token&.line,
|
|
203
|
+
column: token&.column
|
|
204
|
+
)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def take_value_token(value)
|
|
208
|
+
@value_tokens.delete(value.object_id)
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def remember_key(key, token)
|
|
212
|
+
@key_tokens[key.object_id] = token if token
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def contextual_error(error, token)
|
|
216
|
+
return error unless token
|
|
217
|
+
|
|
218
|
+
error.with_context(
|
|
219
|
+
filename: error.filename || @filename,
|
|
220
|
+
byte_offset: error.byte_offset || token.start_byte,
|
|
221
|
+
end_byte_offset: error.end_byte_offset || token.end_byte,
|
|
222
|
+
line: error.line || token.line,
|
|
223
|
+
column: error.column || token.column,
|
|
224
|
+
excerpt: error.excerpt || excerpt_at(token.start_byte)
|
|
225
|
+
)
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
def excerpt_at(byte_offset, radius: 40)
|
|
229
|
+
return nil unless @source
|
|
230
|
+
|
|
231
|
+
start_byte = [byte_offset - radius, 0].max
|
|
232
|
+
finish_byte = [byte_offset + radius, @source.bytesize].min
|
|
233
|
+
@source.byteslice(start_byte...finish_byte)&.scrub
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
end
|
data/lib/json5/token.rb
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JSON5
|
|
4
|
+
class Token
|
|
5
|
+
attr_reader :kind, :value, :start_byte, :end_byte, :line, :column, :leading_trivia
|
|
6
|
+
|
|
7
|
+
def initialize(kind, value, start_byte, end_byte, line, column, raw = nil, leading_trivia = [], source: nil)
|
|
8
|
+
@kind = kind
|
|
9
|
+
@value = value
|
|
10
|
+
@start_byte = start_byte
|
|
11
|
+
@end_byte = end_byte
|
|
12
|
+
@line = line
|
|
13
|
+
@column = column
|
|
14
|
+
@raw = raw&.freeze
|
|
15
|
+
@source = source
|
|
16
|
+
@leading_trivia = leading_trivia
|
|
17
|
+
freeze
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def raw
|
|
21
|
+
@raw || @source&.byteslice(start_byte...end_byte)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
Trivia = Data.define(:kind, :start_byte, :end_byte, :raw)
|
|
26
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JSON5
|
|
4
|
+
module UnicodeTables
|
|
5
|
+
UNICODE_VERSION = "3.0.0".freeze
|
|
6
|
+
UNICODE_DATA_SHA256 = "f41d967bc458ee106f0c3948bfad71cd0860d96c49304e3fd02eaf2bbae4b6d9".freeze
|
|
7
|
+
IDENTIFIER_START_RANGES = [65, 90, 97, 122, 170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 543, 546, 563, 592, 685, 688, 696, 699, 705, 720, 721, 736, 740, 750, 750, 890, 890, 902, 902, 904, 906, 908, 908, 910, 929, 931, 974, 976, 983, 986, 1011, 1024, 1153, 1164, 1220, 1223, 1224, 1227, 1228, 1232, 1269, 1272, 1273, 1329, 1366, 1369, 1369, 1377, 1415, 1488, 1514, 1520, 1522, 1569, 1594, 1600, 1610, 1649, 1747, 1749, 1749, 1765, 1766, 1786, 1788, 1808, 1808, 1810, 1836, 1920, 1957, 2309, 2361, 2365, 2365, 2384, 2384, 2392, 2401, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2524, 2525, 2527, 2529, 2544, 2545, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654, 2674, 2676, 2693, 2699, 2701, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2749, 2749, 2768, 2768, 2784, 2784, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2870, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 2997, 2999, 3001, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3168, 3169, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3294, 3294, 3296, 3297, 3333, 3340, 3342, 3344, 3346, 3368, 3370, 3385, 3424, 3425, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3585, 3632, 3634, 3635, 3648, 3654, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3760, 3762, 3763, 3773, 3773, 3776, 3780, 3782, 3782, 3804, 3805, 3840, 3840, 3904, 3911, 3913, 3946, 3976, 3979, 4096, 4129, 4131, 4135, 4137, 4138, 4176, 4181, 4256, 4293, 4304, 4342, 4352, 4441, 4447, 4514, 4520, 4601, 4608, 4614, 4616, 4678, 4680, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4742, 4744, 4744, 4746, 4749, 4752, 4782, 4784, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4814, 4816, 4822, 4824, 4846, 4848, 4878, 4880, 4880, 4882, 4885, 4888, 4894, 4896, 4934, 4936, 4954, 5024, 5108, 5121, 5740, 5743, 5750, 5761, 5786, 5792, 5866, 6016, 6067, 6176, 6263, 6272, 6312, 7680, 7835, 7840, 7929, 7936, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8319, 8319, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8497, 8499, 8505, 8544, 8579, 12293, 12295, 12321, 12329, 12337, 12341, 12344, 12346, 12353, 12436, 12445, 12446, 12449, 12538, 12540, 12542, 12549, 12588, 12593, 12686, 12704, 12727, 13312, 19893, 19968, 40869, 40960, 42124, 44032, 55203, 63744, 64045, 64256, 64262, 64275, 64279, 64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65136, 65138, 65140, 65140, 65142, 65276, 65313, 65338, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500].freeze
|
|
8
|
+
IDENTIFIER_PART_RANGES = [48, 57, 65, 90, 95, 95, 97, 122, 170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 543, 546, 563, 592, 685, 688, 696, 699, 705, 720, 721, 736, 740, 750, 750, 768, 846, 864, 866, 890, 890, 902, 902, 904, 906, 908, 908, 910, 929, 931, 974, 976, 983, 986, 1011, 1024, 1153, 1155, 1158, 1164, 1220, 1223, 1224, 1227, 1228, 1232, 1269, 1272, 1273, 1329, 1366, 1369, 1369, 1377, 1415, 1425, 1441, 1443, 1465, 1467, 1469, 1471, 1471, 1473, 1474, 1476, 1476, 1488, 1514, 1520, 1522, 1569, 1594, 1600, 1621, 1632, 1641, 1648, 1747, 1749, 1756, 1759, 1768, 1770, 1773, 1776, 1788, 1808, 1836, 1840, 1866, 1920, 1968, 2305, 2307, 2309, 2361, 2364, 2381, 2384, 2388, 2392, 2403, 2406, 2415, 2433, 2435, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2492, 2492, 2494, 2500, 2503, 2504, 2507, 2509, 2519, 2519, 2524, 2525, 2527, 2531, 2534, 2545, 2562, 2562, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2620, 2620, 2622, 2626, 2631, 2632, 2635, 2637, 2649, 2652, 2654, 2654, 2662, 2676, 2689, 2691, 2693, 2699, 2701, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2748, 2757, 2759, 2761, 2763, 2765, 2768, 2768, 2784, 2784, 2790, 2799, 2817, 2819, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2870, 2873, 2876, 2883, 2887, 2888, 2891, 2893, 2902, 2903, 2908, 2909, 2911, 2913, 2918, 2927, 2946, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 2997, 2999, 3001, 3006, 3010, 3014, 3016, 3018, 3021, 3031, 3031, 3047, 3055, 3073, 3075, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3134, 3140, 3142, 3144, 3146, 3149, 3157, 3158, 3168, 3169, 3174, 3183, 3202, 3203, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3262, 3268, 3270, 3272, 3274, 3277, 3285, 3286, 3294, 3294, 3296, 3297, 3302, 3311, 3330, 3331, 3333, 3340, 3342, 3344, 3346, 3368, 3370, 3385, 3390, 3395, 3398, 3400, 3402, 3405, 3415, 3415, 3424, 3425, 3430, 3439, 3458, 3459, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3530, 3530, 3535, 3540, 3542, 3542, 3544, 3551, 3570, 3571, 3585, 3642, 3648, 3662, 3664, 3673, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3769, 3771, 3773, 3776, 3780, 3782, 3782, 3784, 3789, 3792, 3801, 3804, 3805, 3840, 3840, 3864, 3865, 3872, 3881, 3893, 3893, 3895, 3895, 3897, 3897, 3902, 3911, 3913, 3946, 3953, 3972, 3974, 3979, 3984, 3991, 3993, 4028, 4038, 4038, 4096, 4129, 4131, 4135, 4137, 4138, 4140, 4146, 4150, 4153, 4160, 4169, 4176, 4185, 4256, 4293, 4304, 4342, 4352, 4441, 4447, 4514, 4520, 4601, 4608, 4614, 4616, 4678, 4680, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4742, 4744, 4744, 4746, 4749, 4752, 4782, 4784, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4814, 4816, 4822, 4824, 4846, 4848, 4878, 4880, 4880, 4882, 4885, 4888, 4894, 4896, 4934, 4936, 4954, 4969, 4977, 5024, 5108, 5121, 5740, 5743, 5750, 5761, 5786, 5792, 5866, 6016, 6099, 6112, 6121, 6160, 6169, 6176, 6263, 6272, 6313, 7680, 7835, 7840, 7929, 7936, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8255, 8256, 8319, 8319, 8400, 8412, 8417, 8417, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8497, 8499, 8505, 8544, 8579, 12293, 12295, 12321, 12335, 12337, 12341, 12344, 12346, 12353, 12436, 12441, 12442, 12445, 12446, 12449, 12542, 12549, 12588, 12593, 12686, 12704, 12727, 13312, 19893, 19968, 40869, 40960, 42124, 44032, 55203, 63744, 64045, 64256, 64262, 64275, 64279, 64285, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65056, 65059, 65075, 65076, 65101, 65103, 65136, 65138, 65140, 65140, 65142, 65276, 65296, 65305, 65313, 65338, 65343, 65343, 65345, 65370, 65381, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500].freeze
|
|
9
|
+
SPACE_SEPARATOR_RANGES = [32, 32, 160, 160, 5760, 5760, 8192, 8203, 8239, 8239, 12288, 12288].freeze
|
|
10
|
+
|
|
11
|
+
module_function
|
|
12
|
+
|
|
13
|
+
def identifier_start?(codepoint)
|
|
14
|
+
codepoint == 0x24 || codepoint == 0x5f || in_ranges?(IDENTIFIER_START_RANGES, codepoint)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def identifier_part?(codepoint)
|
|
18
|
+
identifier_start?(codepoint) || in_ranges?(IDENTIFIER_PART_RANGES, codepoint) || codepoint == 0x200c || codepoint == 0x200d
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def space_separator?(codepoint)
|
|
22
|
+
in_ranges?(SPACE_SEPARATOR_RANGES, codepoint)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def in_ranges?(ranges, codepoint)
|
|
26
|
+
low = 0
|
|
27
|
+
high = ranges.length / 2
|
|
28
|
+
while low < high
|
|
29
|
+
middle = (low + high) / 2
|
|
30
|
+
start_codepoint = ranges[middle * 2]
|
|
31
|
+
finish_codepoint = ranges[middle * 2 + 1]
|
|
32
|
+
return true if codepoint <= finish_codepoint && codepoint >= start_codepoint
|
|
33
|
+
if codepoint < start_codepoint
|
|
34
|
+
high = middle
|
|
35
|
+
else
|
|
36
|
+
low = middle + 1
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
false
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
data/lib/json5.rb
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "json5/version"
|
|
4
|
+
require_relative "json5/errors"
|
|
5
|
+
require_relative "json5/limits"
|
|
6
|
+
require_relative "json5/diagnostic"
|
|
7
|
+
require_relative "json5/ecma_string"
|
|
8
|
+
require_relative "json5/number_value"
|
|
9
|
+
require_relative "json5/object_value"
|
|
10
|
+
require_relative "json5/input"
|
|
11
|
+
require_relative "json5/line_map"
|
|
12
|
+
require_relative "json5/token"
|
|
13
|
+
require_relative "json5/public_token_names"
|
|
14
|
+
require_relative "json5/ascii_classification"
|
|
15
|
+
require_relative "json5/unicode_tables"
|
|
16
|
+
require_relative "json5/lexer"
|
|
17
|
+
require_relative "json5/ruby_value_builder"
|
|
18
|
+
require_relative "json5/document"
|
|
19
|
+
require_relative "json5/document_nodes"
|
|
20
|
+
require_relative "json5/document_parser"
|
|
21
|
+
require_relative "json5/generated_parser"
|
|
22
|
+
require_relative "json5/parser"
|
|
23
|
+
|
|
24
|
+
module JSON5
|
|
25
|
+
private_constant :GeneratedParser
|
|
26
|
+
|
|
27
|
+
module_function
|
|
28
|
+
|
|
29
|
+
def parse(source, **options)
|
|
30
|
+
Parser.parse(source, **options)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def load(io, **options)
|
|
34
|
+
Parser.load(io, **options)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def valid?(source, **options)
|
|
38
|
+
parse(source, **options)
|
|
39
|
+
true
|
|
40
|
+
rescue JSON5::Error
|
|
41
|
+
false
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def parse_document(source, **options)
|
|
45
|
+
Parser.parse_document(source, **options)
|
|
46
|
+
end
|
|
47
|
+
end
|
data/tool/sources.yml
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
json5:
|
|
2
|
+
specification_version: "1.0.0"
|
|
3
|
+
specification_url: "https://spec.json5.org/"
|
|
4
|
+
source_repository: "https://github.com/json5/json5-spec"
|
|
5
|
+
source_path: "src/index.html"
|
|
6
|
+
source_blob: "36f9418ed339580e362eb370fd084a235e361b8e"
|
|
7
|
+
|
|
8
|
+
ecmascript:
|
|
9
|
+
version: "5.1"
|
|
10
|
+
url: "https://262.ecma-international.org/5.1/"
|
|
11
|
+
|
|
12
|
+
ibex:
|
|
13
|
+
version: "0.3.0"
|
|
14
|
+
repository: "https://github.com/ydah/ibex"
|
|
15
|
+
release: "https://github.com/ydah/ibex/releases/tag/v0.3.0"
|
|
16
|
+
|
|
17
|
+
unicode:
|
|
18
|
+
identifier_profile: "ECMAScript 5.1 baseline"
|
|
19
|
+
data_version: "3.0.0"
|
|
20
|
+
source_url: "https://www.unicode.org/Public/3.0-Update/UnicodeData-3.0.0.txt"
|
|
21
|
+
sha256: "f41d967bc458ee106f0c3948bfad71cd0860d96c49304e3fd02eaf2bbae4b6d9"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Unicode source data
|
|
2
|
+
|
|
3
|
+
`UnicodeData-3.0.0.txt` is the official Unicode 3.0.0 data file used to
|
|
4
|
+
generate the ECMAScript 5.1 `IdentifierName` and `Zs` range tables. The file is
|
|
5
|
+
kept in the repository so regeneration does not depend on the host Ruby's
|
|
6
|
+
Unicode database.
|
|
7
|
+
|
|
8
|
+
- Source: <https://www.unicode.org/Public/3.0-Update/UnicodeData-3.0.0.txt>
|
|
9
|
+
- SHA-256: `f41d967bc458ee106f0c3948bfad71cd0860d96c49304e3fd02eaf2bbae4b6d9`
|
|
10
|
+
- Data version: Unicode 3.0.0
|
|
11
|
+
- License: Unicode License V3. The complete notice is included as
|
|
12
|
+
[`UNICODE-LICENSE.txt`](UNICODE-LICENSE.txt); the authoritative copy is
|
|
13
|
+
<https://www.unicode.org/license.txt>.
|
|
14
|
+
|
|
15
|
+
Regenerate with:
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
ruby script/generate_unicode_tables
|
|
19
|
+
```
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
UNICODE LICENSE V3
|
|
2
|
+
|
|
3
|
+
COPYRIGHT AND PERMISSION NOTICE
|
|
4
|
+
|
|
5
|
+
Copyright © 1991-2026 Unicode, Inc.
|
|
6
|
+
|
|
7
|
+
NOTICE TO USER: Carefully read the following legal agreement. BY
|
|
8
|
+
DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR
|
|
9
|
+
SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE
|
|
10
|
+
TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT
|
|
11
|
+
DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE.
|
|
12
|
+
|
|
13
|
+
Permission is hereby granted, free of charge, to any person obtaining a
|
|
14
|
+
copy of data files and any associated documentation (the "Data Files") or
|
|
15
|
+
software and any associated documentation (the "Software") to deal in the
|
|
16
|
+
Data Files or Software without restriction, including without limitation
|
|
17
|
+
the rights to use, copy, modify, merge, publish, distribute, and/or sell
|
|
18
|
+
copies of the Data Files or Software, and to permit persons to whom the
|
|
19
|
+
Data Files or Software are furnished to do so, provided that either (a)
|
|
20
|
+
this copyright and permission notice appear with all copies of the Data
|
|
21
|
+
Files or Software, or (b) this copyright and permission notice appear in
|
|
22
|
+
associated Documentation.
|
|
23
|
+
|
|
24
|
+
THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
|
25
|
+
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
26
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
|
27
|
+
THIRD PARTY RIGHTS.
|
|
28
|
+
|
|
29
|
+
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE
|
|
30
|
+
BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES,
|
|
31
|
+
OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
|
32
|
+
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
|
33
|
+
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA
|
|
34
|
+
FILES OR SOFTWARE.
|
|
35
|
+
|
|
36
|
+
Except as contained in this notice, the name of a copyright holder shall
|
|
37
|
+
not be used in advertising or otherwise to promote the sale, use or other
|
|
38
|
+
dealings in these Data Files or Software without prior written
|
|
39
|
+
authorization of the copyright holder.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
f41d967bc458ee106f0c3948bfad71cd0860d96c49304e3fd02eaf2bbae4b6d9 UnicodeData-3.0.0.txt
|
metadata
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: json5-ruby
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Yudai Takada
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: ibex
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - '='
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: 0.3.0
|
|
19
|
+
type: :development
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - '='
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: 0.3.0
|
|
26
|
+
description: A strict JSON5 1.0.0 parser implemented in Pure Ruby.
|
|
27
|
+
email:
|
|
28
|
+
- t.yudai92@gmail.com
|
|
29
|
+
executables: []
|
|
30
|
+
extensions: []
|
|
31
|
+
extra_rdoc_files: []
|
|
32
|
+
files:
|
|
33
|
+
- LICENSE.txt
|
|
34
|
+
- NOTICE
|
|
35
|
+
- README.md
|
|
36
|
+
- SECURITY.md
|
|
37
|
+
- docs/conformance-matrix.md
|
|
38
|
+
- docs/conformance-report.md
|
|
39
|
+
- grammar/json5.y
|
|
40
|
+
- lib/json5.rb
|
|
41
|
+
- lib/json5/ascii_classification.rb
|
|
42
|
+
- lib/json5/diagnostic.rb
|
|
43
|
+
- lib/json5/document.rb
|
|
44
|
+
- lib/json5/document_nodes.rb
|
|
45
|
+
- lib/json5/document_parser.rb
|
|
46
|
+
- lib/json5/ecma_string.rb
|
|
47
|
+
- lib/json5/errors.rb
|
|
48
|
+
- lib/json5/generated_parser.ibex.json
|
|
49
|
+
- lib/json5/generated_parser.rb
|
|
50
|
+
- lib/json5/input.rb
|
|
51
|
+
- lib/json5/lexer.rb
|
|
52
|
+
- lib/json5/limits.rb
|
|
53
|
+
- lib/json5/line_map.rb
|
|
54
|
+
- lib/json5/number_value.rb
|
|
55
|
+
- lib/json5/object_value.rb
|
|
56
|
+
- lib/json5/parser.rb
|
|
57
|
+
- lib/json5/public_token_names.rb
|
|
58
|
+
- lib/json5/ruby_value_builder.rb
|
|
59
|
+
- lib/json5/token.rb
|
|
60
|
+
- lib/json5/unicode_tables.rb
|
|
61
|
+
- lib/json5/version.rb
|
|
62
|
+
- tool/sources.yml
|
|
63
|
+
- tool/unicode/README.md
|
|
64
|
+
- tool/unicode/UNICODE-LICENSE.txt
|
|
65
|
+
- tool/unicode/checksums.txt
|
|
66
|
+
homepage: https://github.com/ydah/json5
|
|
67
|
+
licenses:
|
|
68
|
+
- MIT
|
|
69
|
+
metadata:
|
|
70
|
+
homepage_uri: https://github.com/ydah/json5
|
|
71
|
+
source_code_uri: https://github.com/ydah/json5/tree/v0.1.0
|
|
72
|
+
allowed_push_host: https://rubygems.org
|
|
73
|
+
rubygems_mfa_required: 'true'
|
|
74
|
+
rdoc_options: []
|
|
75
|
+
require_paths:
|
|
76
|
+
- lib
|
|
77
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - ">="
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: 3.2.0
|
|
82
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
83
|
+
requirements:
|
|
84
|
+
- - ">="
|
|
85
|
+
- !ruby/object:Gem::Version
|
|
86
|
+
version: '0'
|
|
87
|
+
requirements: []
|
|
88
|
+
rubygems_version: 4.0.6
|
|
89
|
+
specification_version: 4
|
|
90
|
+
summary: A Pure Ruby JSON5 parser
|
|
91
|
+
test_files: []
|