json-kpeg 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.
- data/lib/json-kpeg/escaper.rb +21 -0
- data/lib/json-kpeg/parser.kpeg +48 -0
- data/lib/json-kpeg/parser.kpeg.rb +1199 -0
- data/lib/json-kpeg/version.rb +3 -0
- data/lib/json-kpeg.rb +3 -0
- metadata +86 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module JsonKpeg::StringEscaper
|
|
2
|
+
def process_escapes (str)
|
|
3
|
+
str.gsub! /\\(u\d{4}|\D)/m do
|
|
4
|
+
seq = $1
|
|
5
|
+
case seq
|
|
6
|
+
when '/' then "\/"
|
|
7
|
+
when 'b' then "\b"
|
|
8
|
+
when 'f' then "\f"
|
|
9
|
+
when 'n' then "\n"
|
|
10
|
+
when 'r' then "\r"
|
|
11
|
+
when 't' then "\t"
|
|
12
|
+
when '"' then '"'
|
|
13
|
+
when '\\' then '\\'
|
|
14
|
+
when /u\d{4}/ then seq[1..-1].to_i.chr
|
|
15
|
+
else seq
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
str
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
%% name = JsonKpeg::Parser
|
|
2
|
+
%% {
|
|
3
|
+
require "json-kpeg/escaper"
|
|
4
|
+
include JsonKpeg::StringEscaper
|
|
5
|
+
|
|
6
|
+
attr_reader :result
|
|
7
|
+
attr_accessor :strict
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
value = object
|
|
12
|
+
| array
|
|
13
|
+
| string
|
|
14
|
+
| number
|
|
15
|
+
| "true" { true }
|
|
16
|
+
| "false" { false }
|
|
17
|
+
| "null" { nil }
|
|
18
|
+
|
|
19
|
+
object = "{" - "}" { {} }
|
|
20
|
+
| "{" - object-body:obj - "}" { obj }
|
|
21
|
+
object-body = object-pair:x (- "," - object-pair)*:xs { Hash[[x].concat(xs)] }
|
|
22
|
+
object-pair = string:k - ":" - value:v { [k, v] }
|
|
23
|
+
|
|
24
|
+
array = "[" - "]" { [] }
|
|
25
|
+
| "[" - array-body:arr - "]" { arr }
|
|
26
|
+
array-body = value:x (- "," - value)*:xs { [x].concat(xs) }
|
|
27
|
+
|
|
28
|
+
string = "\"" <string-char+> "\"" { process_escapes(text) }
|
|
29
|
+
string-char = !/["\\]/ .
|
|
30
|
+
| "\\" string-char-escape
|
|
31
|
+
string-char-escape = /[\/\"bfnrt]/
|
|
32
|
+
| "u" /\d{4}/
|
|
33
|
+
|
|
34
|
+
number = number-base:b number-exponent:e { b * (10 ** e) }
|
|
35
|
+
| number-base:b { b }
|
|
36
|
+
number-base = <number-base-whole number-base-frac> { text.to_f }
|
|
37
|
+
| <number-base-whole> { text.to_i }
|
|
38
|
+
number-base-whole = "0" | /-?[1-9]\d*/
|
|
39
|
+
number-base-frac = /\.\d+/
|
|
40
|
+
number-exponent = ("E"|"e") </[+-]?\d+/> { text.to_i }
|
|
41
|
+
|
|
42
|
+
- = /[ \t]*/
|
|
43
|
+
|
|
44
|
+
strict-root = object | array
|
|
45
|
+
root = ( &{self.strict} strict-root:v
|
|
46
|
+
| !{self.strict} value:v
|
|
47
|
+
)
|
|
48
|
+
{ @result = v }
|
|
@@ -0,0 +1,1199 @@
|
|
|
1
|
+
class JsonKpeg::Parser
|
|
2
|
+
# STANDALONE START
|
|
3
|
+
def setup_parser(str, debug=false)
|
|
4
|
+
@string = str
|
|
5
|
+
@pos = 0
|
|
6
|
+
@memoizations = Hash.new { |h,k| h[k] = {} }
|
|
7
|
+
@result = nil
|
|
8
|
+
@failed_rule = nil
|
|
9
|
+
@failing_rule_offset = -1
|
|
10
|
+
|
|
11
|
+
setup_foreign_grammar
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# This is distinct from setup_parser so that a standalone parser
|
|
15
|
+
# can redefine #initialize and still have access to the proper
|
|
16
|
+
# parser setup code.
|
|
17
|
+
#
|
|
18
|
+
def initialize(str, debug=false)
|
|
19
|
+
setup_parser(str, debug)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
attr_reader :string
|
|
23
|
+
attr_reader :failing_rule_offset
|
|
24
|
+
attr_accessor :result, :pos
|
|
25
|
+
|
|
26
|
+
# STANDALONE START
|
|
27
|
+
def current_column(target=pos)
|
|
28
|
+
if c = string.rindex("\n", target-1)
|
|
29
|
+
return target - c - 1
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
target + 1
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def current_line(target=pos)
|
|
36
|
+
cur_offset = 0
|
|
37
|
+
cur_line = 0
|
|
38
|
+
|
|
39
|
+
string.each_line do |line|
|
|
40
|
+
cur_line += 1
|
|
41
|
+
cur_offset += line.size
|
|
42
|
+
return cur_line if cur_offset >= target
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
-1
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def lines
|
|
49
|
+
lines = []
|
|
50
|
+
string.each_line { |l| lines << l }
|
|
51
|
+
lines
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
#
|
|
55
|
+
|
|
56
|
+
def get_text(start)
|
|
57
|
+
@string[start..@pos-1]
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def show_pos
|
|
61
|
+
width = 10
|
|
62
|
+
if @pos < width
|
|
63
|
+
"#{@pos} (\"#{@string[0,@pos]}\" @ \"#{@string[@pos,width]}\")"
|
|
64
|
+
else
|
|
65
|
+
"#{@pos} (\"... #{@string[@pos - width, width]}\" @ \"#{@string[@pos,width]}\")"
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def failure_info
|
|
70
|
+
l = current_line @failing_rule_offset
|
|
71
|
+
c = current_column @failing_rule_offset
|
|
72
|
+
|
|
73
|
+
if @failed_rule.kind_of? Symbol
|
|
74
|
+
info = self.class::Rules[@failed_rule]
|
|
75
|
+
"line #{l}, column #{c}: failed rule '#{info.name}' = '#{info.rendered}'"
|
|
76
|
+
else
|
|
77
|
+
"line #{l}, column #{c}: failed rule '#{@failed_rule}'"
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def failure_caret
|
|
82
|
+
l = current_line @failing_rule_offset
|
|
83
|
+
c = current_column @failing_rule_offset
|
|
84
|
+
|
|
85
|
+
line = lines[l-1]
|
|
86
|
+
"#{line}\n#{' ' * (c - 1)}^"
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def failure_character
|
|
90
|
+
l = current_line @failing_rule_offset
|
|
91
|
+
c = current_column @failing_rule_offset
|
|
92
|
+
lines[l-1][c-1, 1]
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def failure_oneline
|
|
96
|
+
l = current_line @failing_rule_offset
|
|
97
|
+
c = current_column @failing_rule_offset
|
|
98
|
+
|
|
99
|
+
char = lines[l-1][c-1, 1]
|
|
100
|
+
|
|
101
|
+
if @failed_rule.kind_of? Symbol
|
|
102
|
+
info = self.class::Rules[@failed_rule]
|
|
103
|
+
"@#{l}:#{c} failed rule '#{info.name}', got '#{char}'"
|
|
104
|
+
else
|
|
105
|
+
"@#{l}:#{c} failed rule '#{@failed_rule}', got '#{char}'"
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
class ParseError < RuntimeError
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def raise_error
|
|
113
|
+
raise ParseError, failure_oneline
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def show_error(io=STDOUT)
|
|
117
|
+
error_pos = @failing_rule_offset
|
|
118
|
+
line_no = current_line(error_pos)
|
|
119
|
+
col_no = current_column(error_pos)
|
|
120
|
+
|
|
121
|
+
io.puts "On line #{line_no}, column #{col_no}:"
|
|
122
|
+
|
|
123
|
+
if @failed_rule.kind_of? Symbol
|
|
124
|
+
info = self.class::Rules[@failed_rule]
|
|
125
|
+
io.puts "Failed to match '#{info.rendered}' (rule '#{info.name}')"
|
|
126
|
+
else
|
|
127
|
+
io.puts "Failed to match rule '#{@failed_rule}'"
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
io.puts "Got: #{string[error_pos,1].inspect}"
|
|
131
|
+
line = lines[line_no-1]
|
|
132
|
+
io.puts "=> #{line}"
|
|
133
|
+
io.print(" " * (col_no + 3))
|
|
134
|
+
io.puts "^"
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def set_failed_rule(name)
|
|
138
|
+
if @pos > @failing_rule_offset
|
|
139
|
+
@failed_rule = name
|
|
140
|
+
@failing_rule_offset = @pos
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
attr_reader :failed_rule
|
|
145
|
+
|
|
146
|
+
def match_string(str)
|
|
147
|
+
len = str.size
|
|
148
|
+
if @string[pos,len] == str
|
|
149
|
+
@pos += len
|
|
150
|
+
return str
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
return nil
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def scan(reg)
|
|
157
|
+
if m = reg.match(@string[@pos..-1])
|
|
158
|
+
width = m.end(0)
|
|
159
|
+
@pos += width
|
|
160
|
+
return true
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
return nil
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
if "".respond_to? :getbyte
|
|
167
|
+
def get_byte
|
|
168
|
+
if @pos >= @string.size
|
|
169
|
+
return nil
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
s = @string.getbyte @pos
|
|
173
|
+
@pos += 1
|
|
174
|
+
s
|
|
175
|
+
end
|
|
176
|
+
else
|
|
177
|
+
def get_byte
|
|
178
|
+
if @pos >= @string.size
|
|
179
|
+
return nil
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
s = @string[@pos]
|
|
183
|
+
@pos += 1
|
|
184
|
+
s
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def parse(rule=nil)
|
|
189
|
+
if !rule
|
|
190
|
+
_root ? true : false
|
|
191
|
+
else
|
|
192
|
+
# This is not shared with code_generator.rb so this can be standalone
|
|
193
|
+
method = rule.gsub("-","_hyphen_")
|
|
194
|
+
__send__("_#{method}") ? true : false
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
class LeftRecursive
|
|
199
|
+
def initialize(detected=false)
|
|
200
|
+
@detected = detected
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
attr_accessor :detected
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
class MemoEntry
|
|
207
|
+
def initialize(ans, pos)
|
|
208
|
+
@ans = ans
|
|
209
|
+
@pos = pos
|
|
210
|
+
@uses = 1
|
|
211
|
+
@result = nil
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
attr_reader :ans, :pos, :uses, :result
|
|
215
|
+
|
|
216
|
+
def inc!
|
|
217
|
+
@uses += 1
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def move!(ans, pos, result)
|
|
221
|
+
@ans = ans
|
|
222
|
+
@pos = pos
|
|
223
|
+
@result = result
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def external_invoke(other, rule, *args)
|
|
228
|
+
old_pos = @pos
|
|
229
|
+
old_string = @string
|
|
230
|
+
|
|
231
|
+
@pos = other.pos
|
|
232
|
+
@string = other.string
|
|
233
|
+
|
|
234
|
+
begin
|
|
235
|
+
if val = __send__(rule, *args)
|
|
236
|
+
other.pos = @pos
|
|
237
|
+
other.result = @result
|
|
238
|
+
else
|
|
239
|
+
other.set_failed_rule "#{self.class}##{rule}"
|
|
240
|
+
end
|
|
241
|
+
val
|
|
242
|
+
ensure
|
|
243
|
+
@pos = old_pos
|
|
244
|
+
@string = old_string
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def apply_with_args(rule, *args)
|
|
249
|
+
memo_key = [rule, args]
|
|
250
|
+
if m = @memoizations[memo_key][@pos]
|
|
251
|
+
m.inc!
|
|
252
|
+
|
|
253
|
+
prev = @pos
|
|
254
|
+
@pos = m.pos
|
|
255
|
+
if m.ans.kind_of? LeftRecursive
|
|
256
|
+
m.ans.detected = true
|
|
257
|
+
return nil
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
@result = m.result
|
|
261
|
+
|
|
262
|
+
return m.ans
|
|
263
|
+
else
|
|
264
|
+
lr = LeftRecursive.new(false)
|
|
265
|
+
m = MemoEntry.new(lr, @pos)
|
|
266
|
+
@memoizations[memo_key][@pos] = m
|
|
267
|
+
start_pos = @pos
|
|
268
|
+
|
|
269
|
+
ans = __send__ rule, *args
|
|
270
|
+
|
|
271
|
+
m.move! ans, @pos, @result
|
|
272
|
+
|
|
273
|
+
# Don't bother trying to grow the left recursion
|
|
274
|
+
# if it's failing straight away (thus there is no seed)
|
|
275
|
+
if ans and lr.detected
|
|
276
|
+
return grow_lr(rule, args, start_pos, m)
|
|
277
|
+
else
|
|
278
|
+
return ans
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
return ans
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
def apply(rule)
|
|
286
|
+
if m = @memoizations[rule][@pos]
|
|
287
|
+
m.inc!
|
|
288
|
+
|
|
289
|
+
prev = @pos
|
|
290
|
+
@pos = m.pos
|
|
291
|
+
if m.ans.kind_of? LeftRecursive
|
|
292
|
+
m.ans.detected = true
|
|
293
|
+
return nil
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
@result = m.result
|
|
297
|
+
|
|
298
|
+
return m.ans
|
|
299
|
+
else
|
|
300
|
+
lr = LeftRecursive.new(false)
|
|
301
|
+
m = MemoEntry.new(lr, @pos)
|
|
302
|
+
@memoizations[rule][@pos] = m
|
|
303
|
+
start_pos = @pos
|
|
304
|
+
|
|
305
|
+
ans = __send__ rule
|
|
306
|
+
|
|
307
|
+
m.move! ans, @pos, @result
|
|
308
|
+
|
|
309
|
+
# Don't bother trying to grow the left recursion
|
|
310
|
+
# if it's failing straight away (thus there is no seed)
|
|
311
|
+
if ans and lr.detected
|
|
312
|
+
return grow_lr(rule, nil, start_pos, m)
|
|
313
|
+
else
|
|
314
|
+
return ans
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
return ans
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
def grow_lr(rule, args, start_pos, m)
|
|
322
|
+
while true
|
|
323
|
+
@pos = start_pos
|
|
324
|
+
@result = m.result
|
|
325
|
+
|
|
326
|
+
if args
|
|
327
|
+
ans = __send__ rule, *args
|
|
328
|
+
else
|
|
329
|
+
ans = __send__ rule
|
|
330
|
+
end
|
|
331
|
+
return nil unless ans
|
|
332
|
+
|
|
333
|
+
break if @pos <= m.pos
|
|
334
|
+
|
|
335
|
+
m.move! ans, @pos, @result
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
@result = m.result
|
|
339
|
+
@pos = m.pos
|
|
340
|
+
return m.ans
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
class RuleInfo
|
|
344
|
+
def initialize(name, rendered)
|
|
345
|
+
@name = name
|
|
346
|
+
@rendered = rendered
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
attr_reader :name, :rendered
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
def self.rule_info(name, rendered)
|
|
353
|
+
RuleInfo.new(name, rendered)
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
#
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
require "json-kpeg/escaper"
|
|
360
|
+
include JsonKpeg::StringEscaper
|
|
361
|
+
|
|
362
|
+
attr_reader :result
|
|
363
|
+
attr_accessor :strict
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
def setup_foreign_grammar; end
|
|
367
|
+
|
|
368
|
+
# value = (object | array | string | number | "true" { true } | "false" { false } | "null" { nil })
|
|
369
|
+
def _value
|
|
370
|
+
|
|
371
|
+
_save = self.pos
|
|
372
|
+
while true # choice
|
|
373
|
+
_tmp = apply(:_object)
|
|
374
|
+
break if _tmp
|
|
375
|
+
self.pos = _save
|
|
376
|
+
_tmp = apply(:_array)
|
|
377
|
+
break if _tmp
|
|
378
|
+
self.pos = _save
|
|
379
|
+
_tmp = apply(:_string)
|
|
380
|
+
break if _tmp
|
|
381
|
+
self.pos = _save
|
|
382
|
+
_tmp = apply(:_number)
|
|
383
|
+
break if _tmp
|
|
384
|
+
self.pos = _save
|
|
385
|
+
|
|
386
|
+
_save1 = self.pos
|
|
387
|
+
while true # sequence
|
|
388
|
+
_tmp = match_string("true")
|
|
389
|
+
unless _tmp
|
|
390
|
+
self.pos = _save1
|
|
391
|
+
break
|
|
392
|
+
end
|
|
393
|
+
@result = begin; true ; end
|
|
394
|
+
_tmp = true
|
|
395
|
+
unless _tmp
|
|
396
|
+
self.pos = _save1
|
|
397
|
+
end
|
|
398
|
+
break
|
|
399
|
+
end # end sequence
|
|
400
|
+
|
|
401
|
+
break if _tmp
|
|
402
|
+
self.pos = _save
|
|
403
|
+
|
|
404
|
+
_save2 = self.pos
|
|
405
|
+
while true # sequence
|
|
406
|
+
_tmp = match_string("false")
|
|
407
|
+
unless _tmp
|
|
408
|
+
self.pos = _save2
|
|
409
|
+
break
|
|
410
|
+
end
|
|
411
|
+
@result = begin; false ; end
|
|
412
|
+
_tmp = true
|
|
413
|
+
unless _tmp
|
|
414
|
+
self.pos = _save2
|
|
415
|
+
end
|
|
416
|
+
break
|
|
417
|
+
end # end sequence
|
|
418
|
+
|
|
419
|
+
break if _tmp
|
|
420
|
+
self.pos = _save
|
|
421
|
+
|
|
422
|
+
_save3 = self.pos
|
|
423
|
+
while true # sequence
|
|
424
|
+
_tmp = match_string("null")
|
|
425
|
+
unless _tmp
|
|
426
|
+
self.pos = _save3
|
|
427
|
+
break
|
|
428
|
+
end
|
|
429
|
+
@result = begin; nil ; end
|
|
430
|
+
_tmp = true
|
|
431
|
+
unless _tmp
|
|
432
|
+
self.pos = _save3
|
|
433
|
+
end
|
|
434
|
+
break
|
|
435
|
+
end # end sequence
|
|
436
|
+
|
|
437
|
+
break if _tmp
|
|
438
|
+
self.pos = _save
|
|
439
|
+
break
|
|
440
|
+
end # end choice
|
|
441
|
+
|
|
442
|
+
set_failed_rule :_value unless _tmp
|
|
443
|
+
return _tmp
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
# object = ("{" - "}" { {} } | "{" - object-body:obj - "}" { obj })
|
|
447
|
+
def _object
|
|
448
|
+
|
|
449
|
+
_save = self.pos
|
|
450
|
+
while true # choice
|
|
451
|
+
|
|
452
|
+
_save1 = self.pos
|
|
453
|
+
while true # sequence
|
|
454
|
+
_tmp = match_string("{")
|
|
455
|
+
unless _tmp
|
|
456
|
+
self.pos = _save1
|
|
457
|
+
break
|
|
458
|
+
end
|
|
459
|
+
_tmp = apply(:__hyphen_)
|
|
460
|
+
unless _tmp
|
|
461
|
+
self.pos = _save1
|
|
462
|
+
break
|
|
463
|
+
end
|
|
464
|
+
_tmp = match_string("}")
|
|
465
|
+
unless _tmp
|
|
466
|
+
self.pos = _save1
|
|
467
|
+
break
|
|
468
|
+
end
|
|
469
|
+
@result = begin; {} ; end
|
|
470
|
+
_tmp = true
|
|
471
|
+
unless _tmp
|
|
472
|
+
self.pos = _save1
|
|
473
|
+
end
|
|
474
|
+
break
|
|
475
|
+
end # end sequence
|
|
476
|
+
|
|
477
|
+
break if _tmp
|
|
478
|
+
self.pos = _save
|
|
479
|
+
|
|
480
|
+
_save2 = self.pos
|
|
481
|
+
while true # sequence
|
|
482
|
+
_tmp = match_string("{")
|
|
483
|
+
unless _tmp
|
|
484
|
+
self.pos = _save2
|
|
485
|
+
break
|
|
486
|
+
end
|
|
487
|
+
_tmp = apply(:__hyphen_)
|
|
488
|
+
unless _tmp
|
|
489
|
+
self.pos = _save2
|
|
490
|
+
break
|
|
491
|
+
end
|
|
492
|
+
_tmp = apply(:_object_hyphen_body)
|
|
493
|
+
obj = @result
|
|
494
|
+
unless _tmp
|
|
495
|
+
self.pos = _save2
|
|
496
|
+
break
|
|
497
|
+
end
|
|
498
|
+
_tmp = apply(:__hyphen_)
|
|
499
|
+
unless _tmp
|
|
500
|
+
self.pos = _save2
|
|
501
|
+
break
|
|
502
|
+
end
|
|
503
|
+
_tmp = match_string("}")
|
|
504
|
+
unless _tmp
|
|
505
|
+
self.pos = _save2
|
|
506
|
+
break
|
|
507
|
+
end
|
|
508
|
+
@result = begin; obj ; end
|
|
509
|
+
_tmp = true
|
|
510
|
+
unless _tmp
|
|
511
|
+
self.pos = _save2
|
|
512
|
+
end
|
|
513
|
+
break
|
|
514
|
+
end # end sequence
|
|
515
|
+
|
|
516
|
+
break if _tmp
|
|
517
|
+
self.pos = _save
|
|
518
|
+
break
|
|
519
|
+
end # end choice
|
|
520
|
+
|
|
521
|
+
set_failed_rule :_object unless _tmp
|
|
522
|
+
return _tmp
|
|
523
|
+
end
|
|
524
|
+
|
|
525
|
+
# object-body = object-pair:x (- "," - object-pair)*:xs { Hash[[x].concat(xs)] }
|
|
526
|
+
def _object_hyphen_body
|
|
527
|
+
|
|
528
|
+
_save = self.pos
|
|
529
|
+
while true # sequence
|
|
530
|
+
_tmp = apply(:_object_hyphen_pair)
|
|
531
|
+
x = @result
|
|
532
|
+
unless _tmp
|
|
533
|
+
self.pos = _save
|
|
534
|
+
break
|
|
535
|
+
end
|
|
536
|
+
_ary = []
|
|
537
|
+
while true
|
|
538
|
+
|
|
539
|
+
_save2 = self.pos
|
|
540
|
+
while true # sequence
|
|
541
|
+
_tmp = apply(:__hyphen_)
|
|
542
|
+
unless _tmp
|
|
543
|
+
self.pos = _save2
|
|
544
|
+
break
|
|
545
|
+
end
|
|
546
|
+
_tmp = match_string(",")
|
|
547
|
+
unless _tmp
|
|
548
|
+
self.pos = _save2
|
|
549
|
+
break
|
|
550
|
+
end
|
|
551
|
+
_tmp = apply(:__hyphen_)
|
|
552
|
+
unless _tmp
|
|
553
|
+
self.pos = _save2
|
|
554
|
+
break
|
|
555
|
+
end
|
|
556
|
+
_tmp = apply(:_object_hyphen_pair)
|
|
557
|
+
unless _tmp
|
|
558
|
+
self.pos = _save2
|
|
559
|
+
end
|
|
560
|
+
break
|
|
561
|
+
end # end sequence
|
|
562
|
+
|
|
563
|
+
_ary << @result if _tmp
|
|
564
|
+
break unless _tmp
|
|
565
|
+
end
|
|
566
|
+
_tmp = true
|
|
567
|
+
@result = _ary
|
|
568
|
+
xs = @result
|
|
569
|
+
unless _tmp
|
|
570
|
+
self.pos = _save
|
|
571
|
+
break
|
|
572
|
+
end
|
|
573
|
+
@result = begin; Hash[[x].concat(xs)] ; end
|
|
574
|
+
_tmp = true
|
|
575
|
+
unless _tmp
|
|
576
|
+
self.pos = _save
|
|
577
|
+
end
|
|
578
|
+
break
|
|
579
|
+
end # end sequence
|
|
580
|
+
|
|
581
|
+
set_failed_rule :_object_hyphen_body unless _tmp
|
|
582
|
+
return _tmp
|
|
583
|
+
end
|
|
584
|
+
|
|
585
|
+
# object-pair = string:k - ":" - value:v { [k, v] }
|
|
586
|
+
def _object_hyphen_pair
|
|
587
|
+
|
|
588
|
+
_save = self.pos
|
|
589
|
+
while true # sequence
|
|
590
|
+
_tmp = apply(:_string)
|
|
591
|
+
k = @result
|
|
592
|
+
unless _tmp
|
|
593
|
+
self.pos = _save
|
|
594
|
+
break
|
|
595
|
+
end
|
|
596
|
+
_tmp = apply(:__hyphen_)
|
|
597
|
+
unless _tmp
|
|
598
|
+
self.pos = _save
|
|
599
|
+
break
|
|
600
|
+
end
|
|
601
|
+
_tmp = match_string(":")
|
|
602
|
+
unless _tmp
|
|
603
|
+
self.pos = _save
|
|
604
|
+
break
|
|
605
|
+
end
|
|
606
|
+
_tmp = apply(:__hyphen_)
|
|
607
|
+
unless _tmp
|
|
608
|
+
self.pos = _save
|
|
609
|
+
break
|
|
610
|
+
end
|
|
611
|
+
_tmp = apply(:_value)
|
|
612
|
+
v = @result
|
|
613
|
+
unless _tmp
|
|
614
|
+
self.pos = _save
|
|
615
|
+
break
|
|
616
|
+
end
|
|
617
|
+
@result = begin; [k, v] ; end
|
|
618
|
+
_tmp = true
|
|
619
|
+
unless _tmp
|
|
620
|
+
self.pos = _save
|
|
621
|
+
end
|
|
622
|
+
break
|
|
623
|
+
end # end sequence
|
|
624
|
+
|
|
625
|
+
set_failed_rule :_object_hyphen_pair unless _tmp
|
|
626
|
+
return _tmp
|
|
627
|
+
end
|
|
628
|
+
|
|
629
|
+
# array = ("[" - "]" { [] } | "[" - array-body:arr - "]" { arr })
|
|
630
|
+
def _array
|
|
631
|
+
|
|
632
|
+
_save = self.pos
|
|
633
|
+
while true # choice
|
|
634
|
+
|
|
635
|
+
_save1 = self.pos
|
|
636
|
+
while true # sequence
|
|
637
|
+
_tmp = match_string("[")
|
|
638
|
+
unless _tmp
|
|
639
|
+
self.pos = _save1
|
|
640
|
+
break
|
|
641
|
+
end
|
|
642
|
+
_tmp = apply(:__hyphen_)
|
|
643
|
+
unless _tmp
|
|
644
|
+
self.pos = _save1
|
|
645
|
+
break
|
|
646
|
+
end
|
|
647
|
+
_tmp = match_string("]")
|
|
648
|
+
unless _tmp
|
|
649
|
+
self.pos = _save1
|
|
650
|
+
break
|
|
651
|
+
end
|
|
652
|
+
@result = begin; [] ; end
|
|
653
|
+
_tmp = true
|
|
654
|
+
unless _tmp
|
|
655
|
+
self.pos = _save1
|
|
656
|
+
end
|
|
657
|
+
break
|
|
658
|
+
end # end sequence
|
|
659
|
+
|
|
660
|
+
break if _tmp
|
|
661
|
+
self.pos = _save
|
|
662
|
+
|
|
663
|
+
_save2 = self.pos
|
|
664
|
+
while true # sequence
|
|
665
|
+
_tmp = match_string("[")
|
|
666
|
+
unless _tmp
|
|
667
|
+
self.pos = _save2
|
|
668
|
+
break
|
|
669
|
+
end
|
|
670
|
+
_tmp = apply(:__hyphen_)
|
|
671
|
+
unless _tmp
|
|
672
|
+
self.pos = _save2
|
|
673
|
+
break
|
|
674
|
+
end
|
|
675
|
+
_tmp = apply(:_array_hyphen_body)
|
|
676
|
+
arr = @result
|
|
677
|
+
unless _tmp
|
|
678
|
+
self.pos = _save2
|
|
679
|
+
break
|
|
680
|
+
end
|
|
681
|
+
_tmp = apply(:__hyphen_)
|
|
682
|
+
unless _tmp
|
|
683
|
+
self.pos = _save2
|
|
684
|
+
break
|
|
685
|
+
end
|
|
686
|
+
_tmp = match_string("]")
|
|
687
|
+
unless _tmp
|
|
688
|
+
self.pos = _save2
|
|
689
|
+
break
|
|
690
|
+
end
|
|
691
|
+
@result = begin; arr ; end
|
|
692
|
+
_tmp = true
|
|
693
|
+
unless _tmp
|
|
694
|
+
self.pos = _save2
|
|
695
|
+
end
|
|
696
|
+
break
|
|
697
|
+
end # end sequence
|
|
698
|
+
|
|
699
|
+
break if _tmp
|
|
700
|
+
self.pos = _save
|
|
701
|
+
break
|
|
702
|
+
end # end choice
|
|
703
|
+
|
|
704
|
+
set_failed_rule :_array unless _tmp
|
|
705
|
+
return _tmp
|
|
706
|
+
end
|
|
707
|
+
|
|
708
|
+
# array-body = value:x (- "," - value)*:xs { [x].concat(xs) }
|
|
709
|
+
def _array_hyphen_body
|
|
710
|
+
|
|
711
|
+
_save = self.pos
|
|
712
|
+
while true # sequence
|
|
713
|
+
_tmp = apply(:_value)
|
|
714
|
+
x = @result
|
|
715
|
+
unless _tmp
|
|
716
|
+
self.pos = _save
|
|
717
|
+
break
|
|
718
|
+
end
|
|
719
|
+
_ary = []
|
|
720
|
+
while true
|
|
721
|
+
|
|
722
|
+
_save2 = self.pos
|
|
723
|
+
while true # sequence
|
|
724
|
+
_tmp = apply(:__hyphen_)
|
|
725
|
+
unless _tmp
|
|
726
|
+
self.pos = _save2
|
|
727
|
+
break
|
|
728
|
+
end
|
|
729
|
+
_tmp = match_string(",")
|
|
730
|
+
unless _tmp
|
|
731
|
+
self.pos = _save2
|
|
732
|
+
break
|
|
733
|
+
end
|
|
734
|
+
_tmp = apply(:__hyphen_)
|
|
735
|
+
unless _tmp
|
|
736
|
+
self.pos = _save2
|
|
737
|
+
break
|
|
738
|
+
end
|
|
739
|
+
_tmp = apply(:_value)
|
|
740
|
+
unless _tmp
|
|
741
|
+
self.pos = _save2
|
|
742
|
+
end
|
|
743
|
+
break
|
|
744
|
+
end # end sequence
|
|
745
|
+
|
|
746
|
+
_ary << @result if _tmp
|
|
747
|
+
break unless _tmp
|
|
748
|
+
end
|
|
749
|
+
_tmp = true
|
|
750
|
+
@result = _ary
|
|
751
|
+
xs = @result
|
|
752
|
+
unless _tmp
|
|
753
|
+
self.pos = _save
|
|
754
|
+
break
|
|
755
|
+
end
|
|
756
|
+
@result = begin; [x].concat(xs) ; end
|
|
757
|
+
_tmp = true
|
|
758
|
+
unless _tmp
|
|
759
|
+
self.pos = _save
|
|
760
|
+
end
|
|
761
|
+
break
|
|
762
|
+
end # end sequence
|
|
763
|
+
|
|
764
|
+
set_failed_rule :_array_hyphen_body unless _tmp
|
|
765
|
+
return _tmp
|
|
766
|
+
end
|
|
767
|
+
|
|
768
|
+
# string = "\"" < string-char+ > "\"" { process_escapes(text) }
|
|
769
|
+
def _string
|
|
770
|
+
|
|
771
|
+
_save = self.pos
|
|
772
|
+
while true # sequence
|
|
773
|
+
_tmp = match_string("\"")
|
|
774
|
+
unless _tmp
|
|
775
|
+
self.pos = _save
|
|
776
|
+
break
|
|
777
|
+
end
|
|
778
|
+
_text_start = self.pos
|
|
779
|
+
_save1 = self.pos
|
|
780
|
+
_tmp = apply(:_string_hyphen_char)
|
|
781
|
+
if _tmp
|
|
782
|
+
while true
|
|
783
|
+
_tmp = apply(:_string_hyphen_char)
|
|
784
|
+
break unless _tmp
|
|
785
|
+
end
|
|
786
|
+
_tmp = true
|
|
787
|
+
else
|
|
788
|
+
self.pos = _save1
|
|
789
|
+
end
|
|
790
|
+
if _tmp
|
|
791
|
+
text = get_text(_text_start)
|
|
792
|
+
end
|
|
793
|
+
unless _tmp
|
|
794
|
+
self.pos = _save
|
|
795
|
+
break
|
|
796
|
+
end
|
|
797
|
+
_tmp = match_string("\"")
|
|
798
|
+
unless _tmp
|
|
799
|
+
self.pos = _save
|
|
800
|
+
break
|
|
801
|
+
end
|
|
802
|
+
@result = begin; process_escapes(text) ; end
|
|
803
|
+
_tmp = true
|
|
804
|
+
unless _tmp
|
|
805
|
+
self.pos = _save
|
|
806
|
+
end
|
|
807
|
+
break
|
|
808
|
+
end # end sequence
|
|
809
|
+
|
|
810
|
+
set_failed_rule :_string unless _tmp
|
|
811
|
+
return _tmp
|
|
812
|
+
end
|
|
813
|
+
|
|
814
|
+
# string-char = (!/["\\]/ . | "\\" string-char-escape)
|
|
815
|
+
def _string_hyphen_char
|
|
816
|
+
|
|
817
|
+
_save = self.pos
|
|
818
|
+
while true # choice
|
|
819
|
+
|
|
820
|
+
_save1 = self.pos
|
|
821
|
+
while true # sequence
|
|
822
|
+
_save2 = self.pos
|
|
823
|
+
_tmp = scan(/\A(?-mix:["\\])/)
|
|
824
|
+
_tmp = _tmp ? nil : true
|
|
825
|
+
self.pos = _save2
|
|
826
|
+
unless _tmp
|
|
827
|
+
self.pos = _save1
|
|
828
|
+
break
|
|
829
|
+
end
|
|
830
|
+
_tmp = get_byte
|
|
831
|
+
unless _tmp
|
|
832
|
+
self.pos = _save1
|
|
833
|
+
end
|
|
834
|
+
break
|
|
835
|
+
end # end sequence
|
|
836
|
+
|
|
837
|
+
break if _tmp
|
|
838
|
+
self.pos = _save
|
|
839
|
+
|
|
840
|
+
_save3 = self.pos
|
|
841
|
+
while true # sequence
|
|
842
|
+
_tmp = match_string("\\")
|
|
843
|
+
unless _tmp
|
|
844
|
+
self.pos = _save3
|
|
845
|
+
break
|
|
846
|
+
end
|
|
847
|
+
_tmp = apply(:_string_hyphen_char_hyphen_escape)
|
|
848
|
+
unless _tmp
|
|
849
|
+
self.pos = _save3
|
|
850
|
+
end
|
|
851
|
+
break
|
|
852
|
+
end # end sequence
|
|
853
|
+
|
|
854
|
+
break if _tmp
|
|
855
|
+
self.pos = _save
|
|
856
|
+
break
|
|
857
|
+
end # end choice
|
|
858
|
+
|
|
859
|
+
set_failed_rule :_string_hyphen_char unless _tmp
|
|
860
|
+
return _tmp
|
|
861
|
+
end
|
|
862
|
+
|
|
863
|
+
# string-char-escape = (/[\/\"bfnrt]/ | "u" /\d{4}/)
|
|
864
|
+
def _string_hyphen_char_hyphen_escape
|
|
865
|
+
|
|
866
|
+
_save = self.pos
|
|
867
|
+
while true # choice
|
|
868
|
+
_tmp = scan(/\A(?-mix:[\/\"bfnrt])/)
|
|
869
|
+
break if _tmp
|
|
870
|
+
self.pos = _save
|
|
871
|
+
|
|
872
|
+
_save1 = self.pos
|
|
873
|
+
while true # sequence
|
|
874
|
+
_tmp = match_string("u")
|
|
875
|
+
unless _tmp
|
|
876
|
+
self.pos = _save1
|
|
877
|
+
break
|
|
878
|
+
end
|
|
879
|
+
_tmp = scan(/\A(?-mix:\d{4})/)
|
|
880
|
+
unless _tmp
|
|
881
|
+
self.pos = _save1
|
|
882
|
+
end
|
|
883
|
+
break
|
|
884
|
+
end # end sequence
|
|
885
|
+
|
|
886
|
+
break if _tmp
|
|
887
|
+
self.pos = _save
|
|
888
|
+
break
|
|
889
|
+
end # end choice
|
|
890
|
+
|
|
891
|
+
set_failed_rule :_string_hyphen_char_hyphen_escape unless _tmp
|
|
892
|
+
return _tmp
|
|
893
|
+
end
|
|
894
|
+
|
|
895
|
+
# number = (number-base:b number-exponent:e { b * (10 ** e) } | number-base:b { b })
|
|
896
|
+
def _number
|
|
897
|
+
|
|
898
|
+
_save = self.pos
|
|
899
|
+
while true # choice
|
|
900
|
+
|
|
901
|
+
_save1 = self.pos
|
|
902
|
+
while true # sequence
|
|
903
|
+
_tmp = apply(:_number_hyphen_base)
|
|
904
|
+
b = @result
|
|
905
|
+
unless _tmp
|
|
906
|
+
self.pos = _save1
|
|
907
|
+
break
|
|
908
|
+
end
|
|
909
|
+
_tmp = apply(:_number_hyphen_exponent)
|
|
910
|
+
e = @result
|
|
911
|
+
unless _tmp
|
|
912
|
+
self.pos = _save1
|
|
913
|
+
break
|
|
914
|
+
end
|
|
915
|
+
@result = begin; b * (10 ** e) ; end
|
|
916
|
+
_tmp = true
|
|
917
|
+
unless _tmp
|
|
918
|
+
self.pos = _save1
|
|
919
|
+
end
|
|
920
|
+
break
|
|
921
|
+
end # end sequence
|
|
922
|
+
|
|
923
|
+
break if _tmp
|
|
924
|
+
self.pos = _save
|
|
925
|
+
|
|
926
|
+
_save2 = self.pos
|
|
927
|
+
while true # sequence
|
|
928
|
+
_tmp = apply(:_number_hyphen_base)
|
|
929
|
+
b = @result
|
|
930
|
+
unless _tmp
|
|
931
|
+
self.pos = _save2
|
|
932
|
+
break
|
|
933
|
+
end
|
|
934
|
+
@result = begin; b ; end
|
|
935
|
+
_tmp = true
|
|
936
|
+
unless _tmp
|
|
937
|
+
self.pos = _save2
|
|
938
|
+
end
|
|
939
|
+
break
|
|
940
|
+
end # end sequence
|
|
941
|
+
|
|
942
|
+
break if _tmp
|
|
943
|
+
self.pos = _save
|
|
944
|
+
break
|
|
945
|
+
end # end choice
|
|
946
|
+
|
|
947
|
+
set_failed_rule :_number unless _tmp
|
|
948
|
+
return _tmp
|
|
949
|
+
end
|
|
950
|
+
|
|
951
|
+
# number-base = (< number-base-whole number-base-frac > { text.to_f } | < number-base-whole > { text.to_i })
|
|
952
|
+
def _number_hyphen_base
|
|
953
|
+
|
|
954
|
+
_save = self.pos
|
|
955
|
+
while true # choice
|
|
956
|
+
|
|
957
|
+
_save1 = self.pos
|
|
958
|
+
while true # sequence
|
|
959
|
+
_text_start = self.pos
|
|
960
|
+
|
|
961
|
+
_save2 = self.pos
|
|
962
|
+
while true # sequence
|
|
963
|
+
_tmp = apply(:_number_hyphen_base_hyphen_whole)
|
|
964
|
+
unless _tmp
|
|
965
|
+
self.pos = _save2
|
|
966
|
+
break
|
|
967
|
+
end
|
|
968
|
+
_tmp = apply(:_number_hyphen_base_hyphen_frac)
|
|
969
|
+
unless _tmp
|
|
970
|
+
self.pos = _save2
|
|
971
|
+
end
|
|
972
|
+
break
|
|
973
|
+
end # end sequence
|
|
974
|
+
|
|
975
|
+
if _tmp
|
|
976
|
+
text = get_text(_text_start)
|
|
977
|
+
end
|
|
978
|
+
unless _tmp
|
|
979
|
+
self.pos = _save1
|
|
980
|
+
break
|
|
981
|
+
end
|
|
982
|
+
@result = begin; text.to_f ; end
|
|
983
|
+
_tmp = true
|
|
984
|
+
unless _tmp
|
|
985
|
+
self.pos = _save1
|
|
986
|
+
end
|
|
987
|
+
break
|
|
988
|
+
end # end sequence
|
|
989
|
+
|
|
990
|
+
break if _tmp
|
|
991
|
+
self.pos = _save
|
|
992
|
+
|
|
993
|
+
_save3 = self.pos
|
|
994
|
+
while true # sequence
|
|
995
|
+
_text_start = self.pos
|
|
996
|
+
_tmp = apply(:_number_hyphen_base_hyphen_whole)
|
|
997
|
+
if _tmp
|
|
998
|
+
text = get_text(_text_start)
|
|
999
|
+
end
|
|
1000
|
+
unless _tmp
|
|
1001
|
+
self.pos = _save3
|
|
1002
|
+
break
|
|
1003
|
+
end
|
|
1004
|
+
@result = begin; text.to_i ; end
|
|
1005
|
+
_tmp = true
|
|
1006
|
+
unless _tmp
|
|
1007
|
+
self.pos = _save3
|
|
1008
|
+
end
|
|
1009
|
+
break
|
|
1010
|
+
end # end sequence
|
|
1011
|
+
|
|
1012
|
+
break if _tmp
|
|
1013
|
+
self.pos = _save
|
|
1014
|
+
break
|
|
1015
|
+
end # end choice
|
|
1016
|
+
|
|
1017
|
+
set_failed_rule :_number_hyphen_base unless _tmp
|
|
1018
|
+
return _tmp
|
|
1019
|
+
end
|
|
1020
|
+
|
|
1021
|
+
# number-base-whole = ("0" | /-?[1-9]\d*/)
|
|
1022
|
+
def _number_hyphen_base_hyphen_whole
|
|
1023
|
+
|
|
1024
|
+
_save = self.pos
|
|
1025
|
+
while true # choice
|
|
1026
|
+
_tmp = match_string("0")
|
|
1027
|
+
break if _tmp
|
|
1028
|
+
self.pos = _save
|
|
1029
|
+
_tmp = scan(/\A(?-mix:-?[1-9]\d*)/)
|
|
1030
|
+
break if _tmp
|
|
1031
|
+
self.pos = _save
|
|
1032
|
+
break
|
|
1033
|
+
end # end choice
|
|
1034
|
+
|
|
1035
|
+
set_failed_rule :_number_hyphen_base_hyphen_whole unless _tmp
|
|
1036
|
+
return _tmp
|
|
1037
|
+
end
|
|
1038
|
+
|
|
1039
|
+
# number-base-frac = /\.\d+/
|
|
1040
|
+
def _number_hyphen_base_hyphen_frac
|
|
1041
|
+
_tmp = scan(/\A(?-mix:\.\d+)/)
|
|
1042
|
+
set_failed_rule :_number_hyphen_base_hyphen_frac unless _tmp
|
|
1043
|
+
return _tmp
|
|
1044
|
+
end
|
|
1045
|
+
|
|
1046
|
+
# number-exponent = ("E" | "e") < /[+-]?\d+/ > { text.to_i }
|
|
1047
|
+
def _number_hyphen_exponent
|
|
1048
|
+
|
|
1049
|
+
_save = self.pos
|
|
1050
|
+
while true # sequence
|
|
1051
|
+
|
|
1052
|
+
_save1 = self.pos
|
|
1053
|
+
while true # choice
|
|
1054
|
+
_tmp = match_string("E")
|
|
1055
|
+
break if _tmp
|
|
1056
|
+
self.pos = _save1
|
|
1057
|
+
_tmp = match_string("e")
|
|
1058
|
+
break if _tmp
|
|
1059
|
+
self.pos = _save1
|
|
1060
|
+
break
|
|
1061
|
+
end # end choice
|
|
1062
|
+
|
|
1063
|
+
unless _tmp
|
|
1064
|
+
self.pos = _save
|
|
1065
|
+
break
|
|
1066
|
+
end
|
|
1067
|
+
_text_start = self.pos
|
|
1068
|
+
_tmp = scan(/\A(?-mix:[+-]?\d+)/)
|
|
1069
|
+
if _tmp
|
|
1070
|
+
text = get_text(_text_start)
|
|
1071
|
+
end
|
|
1072
|
+
unless _tmp
|
|
1073
|
+
self.pos = _save
|
|
1074
|
+
break
|
|
1075
|
+
end
|
|
1076
|
+
@result = begin; text.to_i ; end
|
|
1077
|
+
_tmp = true
|
|
1078
|
+
unless _tmp
|
|
1079
|
+
self.pos = _save
|
|
1080
|
+
end
|
|
1081
|
+
break
|
|
1082
|
+
end # end sequence
|
|
1083
|
+
|
|
1084
|
+
set_failed_rule :_number_hyphen_exponent unless _tmp
|
|
1085
|
+
return _tmp
|
|
1086
|
+
end
|
|
1087
|
+
|
|
1088
|
+
# - = /[ \t]*/
|
|
1089
|
+
def __hyphen_
|
|
1090
|
+
_tmp = scan(/\A(?-mix:[ \t]*)/)
|
|
1091
|
+
set_failed_rule :__hyphen_ unless _tmp
|
|
1092
|
+
return _tmp
|
|
1093
|
+
end
|
|
1094
|
+
|
|
1095
|
+
# strict-root = (object | array)
|
|
1096
|
+
def _strict_hyphen_root
|
|
1097
|
+
|
|
1098
|
+
_save = self.pos
|
|
1099
|
+
while true # choice
|
|
1100
|
+
_tmp = apply(:_object)
|
|
1101
|
+
break if _tmp
|
|
1102
|
+
self.pos = _save
|
|
1103
|
+
_tmp = apply(:_array)
|
|
1104
|
+
break if _tmp
|
|
1105
|
+
self.pos = _save
|
|
1106
|
+
break
|
|
1107
|
+
end # end choice
|
|
1108
|
+
|
|
1109
|
+
set_failed_rule :_strict_hyphen_root unless _tmp
|
|
1110
|
+
return _tmp
|
|
1111
|
+
end
|
|
1112
|
+
|
|
1113
|
+
# root = (&{self.strict} strict-root:v | !{self.strict} value:v) { @result = v }
|
|
1114
|
+
def _root
|
|
1115
|
+
|
|
1116
|
+
_save = self.pos
|
|
1117
|
+
while true # sequence
|
|
1118
|
+
|
|
1119
|
+
_save1 = self.pos
|
|
1120
|
+
while true # choice
|
|
1121
|
+
|
|
1122
|
+
_save2 = self.pos
|
|
1123
|
+
while true # sequence
|
|
1124
|
+
_save3 = self.pos
|
|
1125
|
+
_tmp = begin; self.strict; end
|
|
1126
|
+
self.pos = _save3
|
|
1127
|
+
unless _tmp
|
|
1128
|
+
self.pos = _save2
|
|
1129
|
+
break
|
|
1130
|
+
end
|
|
1131
|
+
_tmp = apply(:_strict_hyphen_root)
|
|
1132
|
+
v = @result
|
|
1133
|
+
unless _tmp
|
|
1134
|
+
self.pos = _save2
|
|
1135
|
+
end
|
|
1136
|
+
break
|
|
1137
|
+
end # end sequence
|
|
1138
|
+
|
|
1139
|
+
break if _tmp
|
|
1140
|
+
self.pos = _save1
|
|
1141
|
+
|
|
1142
|
+
_save4 = self.pos
|
|
1143
|
+
while true # sequence
|
|
1144
|
+
_save5 = self.pos
|
|
1145
|
+
_tmp = begin; self.strict; end
|
|
1146
|
+
_tmp = _tmp ? nil : true
|
|
1147
|
+
self.pos = _save5
|
|
1148
|
+
unless _tmp
|
|
1149
|
+
self.pos = _save4
|
|
1150
|
+
break
|
|
1151
|
+
end
|
|
1152
|
+
_tmp = apply(:_value)
|
|
1153
|
+
v = @result
|
|
1154
|
+
unless _tmp
|
|
1155
|
+
self.pos = _save4
|
|
1156
|
+
end
|
|
1157
|
+
break
|
|
1158
|
+
end # end sequence
|
|
1159
|
+
|
|
1160
|
+
break if _tmp
|
|
1161
|
+
self.pos = _save1
|
|
1162
|
+
break
|
|
1163
|
+
end # end choice
|
|
1164
|
+
|
|
1165
|
+
unless _tmp
|
|
1166
|
+
self.pos = _save
|
|
1167
|
+
break
|
|
1168
|
+
end
|
|
1169
|
+
@result = begin; @result = v ; end
|
|
1170
|
+
_tmp = true
|
|
1171
|
+
unless _tmp
|
|
1172
|
+
self.pos = _save
|
|
1173
|
+
end
|
|
1174
|
+
break
|
|
1175
|
+
end # end sequence
|
|
1176
|
+
|
|
1177
|
+
set_failed_rule :_root unless _tmp
|
|
1178
|
+
return _tmp
|
|
1179
|
+
end
|
|
1180
|
+
|
|
1181
|
+
Rules = {}
|
|
1182
|
+
Rules[:_value] = rule_info("value", "(object | array | string | number | \"true\" { true } | \"false\" { false } | \"null\" { nil })")
|
|
1183
|
+
Rules[:_object] = rule_info("object", "(\"{\" - \"}\" { {} } | \"{\" - object-body:obj - \"}\" { obj })")
|
|
1184
|
+
Rules[:_object_hyphen_body] = rule_info("object-body", "object-pair:x (- \",\" - object-pair)*:xs { Hash[[x].concat(xs)] }")
|
|
1185
|
+
Rules[:_object_hyphen_pair] = rule_info("object-pair", "string:k - \":\" - value:v { [k, v] }")
|
|
1186
|
+
Rules[:_array] = rule_info("array", "(\"[\" - \"]\" { [] } | \"[\" - array-body:arr - \"]\" { arr })")
|
|
1187
|
+
Rules[:_array_hyphen_body] = rule_info("array-body", "value:x (- \",\" - value)*:xs { [x].concat(xs) }")
|
|
1188
|
+
Rules[:_string] = rule_info("string", "\"\\\"\" < string-char+ > \"\\\"\" { process_escapes(text) }")
|
|
1189
|
+
Rules[:_string_hyphen_char] = rule_info("string-char", "(!/[\"\\\\]/ . | \"\\\\\" string-char-escape)")
|
|
1190
|
+
Rules[:_string_hyphen_char_hyphen_escape] = rule_info("string-char-escape", "(/[\\/\\\"bfnrt]/ | \"u\" /\\d{4}/)")
|
|
1191
|
+
Rules[:_number] = rule_info("number", "(number-base:b number-exponent:e { b * (10 ** e) } | number-base:b { b })")
|
|
1192
|
+
Rules[:_number_hyphen_base] = rule_info("number-base", "(< number-base-whole number-base-frac > { text.to_f } | < number-base-whole > { text.to_i })")
|
|
1193
|
+
Rules[:_number_hyphen_base_hyphen_whole] = rule_info("number-base-whole", "(\"0\" | /-?[1-9]\\d*/)")
|
|
1194
|
+
Rules[:_number_hyphen_base_hyphen_frac] = rule_info("number-base-frac", "/\\.\\d+/")
|
|
1195
|
+
Rules[:_number_hyphen_exponent] = rule_info("number-exponent", "(\"E\" | \"e\") < /[+-]?\\d+/ > { text.to_i }")
|
|
1196
|
+
Rules[:__hyphen_] = rule_info("-", "/[ \\t]*/")
|
|
1197
|
+
Rules[:_strict_hyphen_root] = rule_info("strict-root", "(object | array)")
|
|
1198
|
+
Rules[:_root] = rule_info("root", "(&{self.strict} strict-root:v | !{self.strict} value:v) { @result = v }")
|
|
1199
|
+
end
|
data/lib/json-kpeg.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: json-kpeg
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
hash: 27
|
|
5
|
+
prerelease:
|
|
6
|
+
segments:
|
|
7
|
+
- 0
|
|
8
|
+
- 1
|
|
9
|
+
- 0
|
|
10
|
+
version: 0.1.0
|
|
11
|
+
platform: ruby
|
|
12
|
+
authors:
|
|
13
|
+
- Jonathan Castello
|
|
14
|
+
autorequire:
|
|
15
|
+
bindir: bin
|
|
16
|
+
cert_chain: []
|
|
17
|
+
|
|
18
|
+
date: 2011-05-16 00:00:00 -07:00
|
|
19
|
+
default_executable:
|
|
20
|
+
dependencies:
|
|
21
|
+
- !ruby/object:Gem::Dependency
|
|
22
|
+
name: bundler
|
|
23
|
+
prerelease: false
|
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
|
25
|
+
none: false
|
|
26
|
+
requirements:
|
|
27
|
+
- - ~>
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
hash: 23
|
|
30
|
+
segments:
|
|
31
|
+
- 1
|
|
32
|
+
- 0
|
|
33
|
+
- 0
|
|
34
|
+
version: 1.0.0
|
|
35
|
+
type: :development
|
|
36
|
+
version_requirements: *id001
|
|
37
|
+
description: A simple JSON parser implemented using kpeg.
|
|
38
|
+
email: jonathan@jonathan.com
|
|
39
|
+
executables: []
|
|
40
|
+
|
|
41
|
+
extensions: []
|
|
42
|
+
|
|
43
|
+
extra_rdoc_files: []
|
|
44
|
+
|
|
45
|
+
files:
|
|
46
|
+
- lib/json-kpeg.rb
|
|
47
|
+
- lib/json-kpeg/escaper.rb
|
|
48
|
+
- lib/json-kpeg/parser.kpeg
|
|
49
|
+
- lib/json-kpeg/parser.kpeg.rb
|
|
50
|
+
- lib/json-kpeg/version.rb
|
|
51
|
+
has_rdoc: true
|
|
52
|
+
homepage: https://github.com/Twisol/json-kpeg
|
|
53
|
+
licenses:
|
|
54
|
+
- MIT
|
|
55
|
+
post_install_message:
|
|
56
|
+
rdoc_options: []
|
|
57
|
+
|
|
58
|
+
require_paths:
|
|
59
|
+
- lib
|
|
60
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
61
|
+
none: false
|
|
62
|
+
requirements:
|
|
63
|
+
- - ">="
|
|
64
|
+
- !ruby/object:Gem::Version
|
|
65
|
+
hash: 3
|
|
66
|
+
segments:
|
|
67
|
+
- 0
|
|
68
|
+
version: "0"
|
|
69
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
70
|
+
none: false
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
hash: 3
|
|
75
|
+
segments:
|
|
76
|
+
- 0
|
|
77
|
+
version: "0"
|
|
78
|
+
requirements: []
|
|
79
|
+
|
|
80
|
+
rubyforge_project:
|
|
81
|
+
rubygems_version: 1.5.2
|
|
82
|
+
signing_key:
|
|
83
|
+
specification_version: 3
|
|
84
|
+
summary: A JSON parser implemented using kpeg.
|
|
85
|
+
test_files: []
|
|
86
|
+
|