kdl 0.1.0 → 1.0.0.rc2

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.
@@ -0,0 +1,502 @@
1
+ #
2
+ # DO NOT MODIFY!!!!
3
+ # This file is automatically generated by Racc 1.5.2
4
+ # from Racc grammar file "".
5
+ #
6
+
7
+ require 'racc/parser.rb'
8
+ module KDL
9
+ class Parser < Racc::Parser
10
+
11
+ module_eval(<<'...end kdl.yy/module_eval...', 'kdl.yy', 69)
12
+
13
+ def parse(str, options = {})
14
+ if options.fetch(:parse_types, true)
15
+ @type_parsers = ::KDL::Types::MAPPING.merge(options.fetch(:type_parsers, {}))
16
+ else
17
+ @type_parsers = {}
18
+ end
19
+ @tokenizer = ::KDL::Tokenizer.new(str)
20
+ do_parse
21
+ end
22
+
23
+ private
24
+
25
+ def next_token
26
+ @tokenizer.next_token
27
+ end
28
+ ...end kdl.yy/module_eval...
29
+ ##### State transition tables begin ###
30
+
31
+ racc_action_table = [
32
+ -2, 10, 19, 20, 21, 19, 20, 21, 6, 7,
33
+ 6, 7, 45, 25, 18, 38, 8, 18, 8, 17,
34
+ 58, 32, 17, 19, 47, 48, 52, 53, 56, 57,
35
+ 55, 45, 38, -43, 62, 18, 19, 20, 21, 38,
36
+ 43, -29, -30, 19, 20, 21, 64, 74, 18, 19,
37
+ 20, 21, nil, 17, 75, 18, 19, 20, 21, nil,
38
+ 17, 18, 19, 47, 48, 52, 53, 56, 57, 55,
39
+ nil, nil, 58, nil, 18, 66, 67, 52, 53, 56,
40
+ 57, 55, 30, 7, nil, nil, 18, 6, 7, 35,
41
+ 8, 32, 6, 7, 35, 8, 6, 7, nil, 35,
42
+ 8, 6, 7, nil, 8, 6, 7, 6, 7, 8,
43
+ 6, 7, nil, 8, nil, 8, nil, nil, 8, 66,
44
+ 67, 52, 53, 56, 57, 55, 19, 20, 21 ]
45
+
46
+ racc_action_check = [
47
+ 3, 1, 2, 2, 2, 5, 5, 5, 0, 0,
48
+ 3, 3, 45, 10, 2, 17, 0, 5, 3, 2,
49
+ 31, 45, 5, 30, 30, 30, 30, 30, 30, 30,
50
+ 30, 30, 32, 30, 39, 30, 68, 68, 68, 43,
51
+ 30, 47, 48, 69, 69, 69, 49, 68, 68, 37,
52
+ 37, 37, nil, 68, 69, 69, 14, 14, 14, nil,
53
+ 69, 37, 63, 63, 63, 63, 63, 63, 63, 63,
54
+ nil, nil, 63, nil, 63, 64, 64, 64, 64, 64,
55
+ 64, 64, 15, 15, nil, nil, 64, 28, 28, 15,
56
+ 15, 15, 29, 29, 28, 28, 33, 33, nil, 29,
57
+ 29, 35, 35, nil, 33, 58, 58, 60, 60, 35,
58
+ 70, 70, nil, 58, nil, 60, nil, nil, 70, 51,
59
+ 51, 51, 51, 51, 51, 51, 18, 18, 18 ]
60
+
61
+ racc_action_pointer = [
62
+ -2, 1, 0, 0, nil, 3, nil, nil, nil, nil,
63
+ 13, nil, nil, nil, 54, 72, nil, 5, 124, nil,
64
+ nil, nil, nil, nil, nil, nil, nil, nil, 77, 82,
65
+ 21, 8, 22, 86, nil, 91, nil, 47, nil, 19,
66
+ nil, nil, nil, 29, nil, 2, nil, 25, 26, 30,
67
+ nil, 116, nil, nil, nil, nil, nil, nil, 95, nil,
68
+ 97, nil, nil, 60, 72, nil, nil, nil, 34, 41,
69
+ 100, nil, nil, nil, nil, nil ]
70
+
71
+ racc_action_default = [
72
+ -51, -52, -1, -50, -3, -52, -44, -45, -46, -47,
73
+ -52, -6, -7, -8, -52, -51, -13, -51, -52, -28,
74
+ -29, -30, -48, -4, -5, 76, -9, -10, -52, -52,
75
+ -44, -52, -51, -23, -24, -25, -42, -52, -43, -52,
76
+ -11, -12, -14, -51, -16, -52, -22, -34, -35, -52,
77
+ -32, -52, -36, -37, -38, -39, -40, -41, -51, -21,
78
+ -26, -18, -27, -52, -52, -33, -34, -35, -52, -52,
79
+ -50, -15, -17, -31, -20, -19 ]
80
+
81
+ racc_goto_table = [
82
+ 22, 23, 24, 2, 3, 4, 39, 51, 5, 42,
83
+ 37, 44, 27, 1, 26, 28, 29, 65, 49, nil,
84
+ nil, nil, nil, nil, nil, 40, 41, nil, nil, nil,
85
+ 22, nil, nil, 61, nil, nil, 63, nil, nil, 60,
86
+ 51, 51, 71, 73, 72, nil, nil, nil, nil, nil,
87
+ nil, 49, nil, nil, nil, nil, nil, 22, nil, nil,
88
+ nil, 69, 70, 4, 23, 24, 68, 22 ]
89
+
90
+ racc_goto_check = [
91
+ 21, 6, 7, 2, 3, 4, 14, 9, 5, 15,
92
+ 16, 17, 11, 1, 8, 12, 13, 19, 14, nil,
93
+ nil, nil, nil, nil, nil, 11, 11, nil, nil, nil,
94
+ 21, nil, nil, 6, nil, nil, 16, nil, nil, 3,
95
+ 9, 9, 15, 15, 17, nil, nil, nil, nil, nil,
96
+ nil, 14, nil, nil, nil, nil, nil, 21, nil, nil,
97
+ nil, 2, 3, 4, 6, 7, 5, 21 ]
98
+
99
+ racc_goto_pointer = [
100
+ nil, 13, 3, 4, 5, 8, -4, -3, 0, -23,
101
+ nil, -3, 0, 1, -12, -21, -7, -19, nil, -34,
102
+ nil, -3 ]
103
+
104
+ racc_goto_default = [
105
+ nil, nil, nil, 33, 36, nil, 11, 12, 13, 14,
106
+ 15, nil, 59, 46, 16, nil, 31, nil, 34, 50,
107
+ 54, 9 ]
108
+
109
+ racc_reduce_table = [
110
+ 0, 0, :racc_error,
111
+ 1, 21, :_reduce_1,
112
+ 1, 21, :_reduce_2,
113
+ 1, 22, :_reduce_3,
114
+ 2, 22, :_reduce_4,
115
+ 2, 22, :_reduce_5,
116
+ 2, 22, :_reduce_6,
117
+ 2, 22, :_reduce_7,
118
+ 1, 26, :_reduce_8,
119
+ 2, 26, :_reduce_9,
120
+ 2, 28, :_reduce_10,
121
+ 3, 28, :_reduce_11,
122
+ 3, 28, :_reduce_12,
123
+ 1, 30, :_reduce_13,
124
+ 3, 30, :_reduce_14,
125
+ 5, 30, :_reduce_15,
126
+ 3, 30, :_reduce_16,
127
+ 5, 30, :_reduce_17,
128
+ 3, 27, :_reduce_none,
129
+ 4, 32, :_reduce_19,
130
+ 4, 32, :_reduce_20,
131
+ 2, 33, :_reduce_none,
132
+ 2, 33, :_reduce_none,
133
+ 1, 31, :_reduce_none,
134
+ 1, 31, :_reduce_none,
135
+ 1, 38, :_reduce_none,
136
+ 2, 38, :_reduce_none,
137
+ 3, 29, :_reduce_27,
138
+ 1, 34, :_reduce_28,
139
+ 1, 34, :_reduce_29,
140
+ 1, 34, :_reduce_30,
141
+ 3, 37, :_reduce_31,
142
+ 1, 35, :_reduce_none,
143
+ 2, 35, :_reduce_33,
144
+ 1, 39, :_reduce_34,
145
+ 1, 39, :_reduce_35,
146
+ 1, 39, :_reduce_36,
147
+ 1, 39, :_reduce_37,
148
+ 1, 39, :_reduce_38,
149
+ 1, 39, :_reduce_39,
150
+ 1, 40, :_reduce_40,
151
+ 1, 40, :_reduce_41,
152
+ 1, 36, :_reduce_none,
153
+ 1, 36, :_reduce_none,
154
+ 1, 41, :_reduce_none,
155
+ 1, 41, :_reduce_none,
156
+ 1, 41, :_reduce_none,
157
+ 1, 23, :_reduce_none,
158
+ 2, 23, :_reduce_none,
159
+ 1, 25, :_reduce_none,
160
+ 1, 25, :_reduce_none,
161
+ 0, 24, :_reduce_51 ]
162
+
163
+ racc_reduce_n = 52
164
+
165
+ racc_shift_n = 76
166
+
167
+ racc_token_table = {
168
+ false => 0,
169
+ :error => 1,
170
+ :IDENT => 2,
171
+ :STRING => 3,
172
+ :RAWSTRING => 4,
173
+ :INTEGER => 5,
174
+ :FLOAT => 6,
175
+ :TRUE => 7,
176
+ :FALSE => 8,
177
+ :NULL => 9,
178
+ :WS => 10,
179
+ :NEWLINE => 11,
180
+ :LBRACE => 12,
181
+ :RBRACE => 13,
182
+ :LPAREN => 14,
183
+ :RPAREN => 15,
184
+ :EQUALS => 16,
185
+ :SEMICOLON => 17,
186
+ :EOF => 18,
187
+ :SLASHDASH => 19 }
188
+
189
+ racc_nt_base = 20
190
+
191
+ racc_use_result_var = false
192
+
193
+ Racc_arg = [
194
+ racc_action_table,
195
+ racc_action_check,
196
+ racc_action_default,
197
+ racc_action_pointer,
198
+ racc_goto_table,
199
+ racc_goto_check,
200
+ racc_goto_default,
201
+ racc_goto_pointer,
202
+ racc_nt_base,
203
+ racc_reduce_table,
204
+ racc_token_table,
205
+ racc_shift_n,
206
+ racc_reduce_n,
207
+ racc_use_result_var ]
208
+
209
+ Racc_token_to_s_table = [
210
+ "$end",
211
+ "error",
212
+ "IDENT",
213
+ "STRING",
214
+ "RAWSTRING",
215
+ "INTEGER",
216
+ "FLOAT",
217
+ "TRUE",
218
+ "FALSE",
219
+ "NULL",
220
+ "WS",
221
+ "NEWLINE",
222
+ "LBRACE",
223
+ "RBRACE",
224
+ "LPAREN",
225
+ "RPAREN",
226
+ "EQUALS",
227
+ "SEMICOLON",
228
+ "EOF",
229
+ "SLASHDASH",
230
+ "$start",
231
+ "document",
232
+ "nodes",
233
+ "linespaces",
234
+ "none",
235
+ "linespace_star",
236
+ "node",
237
+ "empty_node",
238
+ "untyped_node",
239
+ "type",
240
+ "node_decl",
241
+ "node_term",
242
+ "node_children",
243
+ "empty_children",
244
+ "identifier",
245
+ "value",
246
+ "ws_star",
247
+ "property",
248
+ "semicolon_term",
249
+ "untyped_value",
250
+ "boolean",
251
+ "linespace" ]
252
+
253
+ Racc_debug_parser = false
254
+
255
+ ##### State transition tables end #####
256
+
257
+ # reduce 0 omitted
258
+
259
+ module_eval(<<'.,.,', 'kdl.yy', 13)
260
+ def _reduce_1(val, _values)
261
+ KDL::Document.new(val[0])
262
+ end
263
+ .,.,
264
+
265
+ module_eval(<<'.,.,', 'kdl.yy', 14)
266
+ def _reduce_2(val, _values)
267
+ KDL::Document.new([])
268
+ end
269
+ .,.,
270
+
271
+ module_eval(<<'.,.,', 'kdl.yy', 16)
272
+ def _reduce_3(val, _values)
273
+ []
274
+ end
275
+ .,.,
276
+
277
+ module_eval(<<'.,.,', 'kdl.yy', 17)
278
+ def _reduce_4(val, _values)
279
+ [val[1]]
280
+ end
281
+ .,.,
282
+
283
+ module_eval(<<'.,.,', 'kdl.yy', 18)
284
+ def _reduce_5(val, _values)
285
+ []
286
+ end
287
+ .,.,
288
+
289
+ module_eval(<<'.,.,', 'kdl.yy', 19)
290
+ def _reduce_6(val, _values)
291
+ [*val[0], val[1]]
292
+ end
293
+ .,.,
294
+
295
+ module_eval(<<'.,.,', 'kdl.yy', 20)
296
+ def _reduce_7(val, _values)
297
+ val[0]
298
+ end
299
+ .,.,
300
+
301
+ module_eval(<<'.,.,', 'kdl.yy', 21)
302
+ def _reduce_8(val, _values)
303
+ val[0]
304
+ end
305
+ .,.,
306
+
307
+ module_eval(<<'.,.,', 'kdl.yy', 22)
308
+ def _reduce_9(val, _values)
309
+ val[1].as_type(val[0], @type_parsers.fetch(val[0], nil))
310
+ end
311
+ .,.,
312
+
313
+ module_eval(<<'.,.,', 'kdl.yy', 23)
314
+ def _reduce_10(val, _values)
315
+ val[0].tap { |x| x.children = nil }
316
+ end
317
+ .,.,
318
+
319
+ module_eval(<<'.,.,', 'kdl.yy', 24)
320
+ def _reduce_11(val, _values)
321
+ val[0].tap { |x| x.children = val[1] }
322
+ end
323
+ .,.,
324
+
325
+ module_eval(<<'.,.,', 'kdl.yy', 25)
326
+ def _reduce_12(val, _values)
327
+ val[0].tap { |x| x.children = nil }
328
+ end
329
+ .,.,
330
+
331
+ module_eval(<<'.,.,', 'kdl.yy', 26)
332
+ def _reduce_13(val, _values)
333
+ KDL::Node.new(val[0])
334
+ end
335
+ .,.,
336
+
337
+ module_eval(<<'.,.,', 'kdl.yy', 27)
338
+ def _reduce_14(val, _values)
339
+ val[0].tap { |x| x.arguments << val[2] }
340
+ end
341
+ .,.,
342
+
343
+ module_eval(<<'.,.,', 'kdl.yy', 28)
344
+ def _reduce_15(val, _values)
345
+ val[0]
346
+ end
347
+ .,.,
348
+
349
+ module_eval(<<'.,.,', 'kdl.yy', 29)
350
+ def _reduce_16(val, _values)
351
+ val[0].tap { |x| x.properties[val[2][0]] = val[2][1] }
352
+ end
353
+ .,.,
354
+
355
+ module_eval(<<'.,.,', 'kdl.yy', 30)
356
+ def _reduce_17(val, _values)
357
+ val[0]
358
+ end
359
+ .,.,
360
+
361
+ # reduce 18 omitted
362
+
363
+ module_eval(<<'.,.,', 'kdl.yy', 32)
364
+ def _reduce_19(val, _values)
365
+ val[2]
366
+ end
367
+ .,.,
368
+
369
+ module_eval(<<'.,.,', 'kdl.yy', 33)
370
+ def _reduce_20(val, _values)
371
+ []
372
+ end
373
+ .,.,
374
+
375
+ # reduce 21 omitted
376
+
377
+ # reduce 22 omitted
378
+
379
+ # reduce 23 omitted
380
+
381
+ # reduce 24 omitted
382
+
383
+ # reduce 25 omitted
384
+
385
+ # reduce 26 omitted
386
+
387
+ module_eval(<<'.,.,', 'kdl.yy', 39)
388
+ def _reduce_27(val, _values)
389
+ val[1]
390
+ end
391
+ .,.,
392
+
393
+ module_eval(<<'.,.,', 'kdl.yy', 41)
394
+ def _reduce_28(val, _values)
395
+ val[0].value
396
+ end
397
+ .,.,
398
+
399
+ module_eval(<<'.,.,', 'kdl.yy', 42)
400
+ def _reduce_29(val, _values)
401
+ val[0].value
402
+ end
403
+ .,.,
404
+
405
+ module_eval(<<'.,.,', 'kdl.yy', 43)
406
+ def _reduce_30(val, _values)
407
+ val[0].value
408
+ end
409
+ .,.,
410
+
411
+ module_eval(<<'.,.,', 'kdl.yy', 45)
412
+ def _reduce_31(val, _values)
413
+ [val[0], val[2]]
414
+ end
415
+ .,.,
416
+
417
+ # reduce 32 omitted
418
+
419
+ module_eval(<<'.,.,', 'kdl.yy', 48)
420
+ def _reduce_33(val, _values)
421
+ val[1].as_type(val[0], @type_parsers.fetch(val[0], nil))
422
+ end
423
+ .,.,
424
+
425
+ module_eval(<<'.,.,', 'kdl.yy', 50)
426
+ def _reduce_34(val, _values)
427
+ KDL::Value::String.new(val[0].value)
428
+ end
429
+ .,.,
430
+
431
+ module_eval(<<'.,.,', 'kdl.yy', 51)
432
+ def _reduce_35(val, _values)
433
+ KDL::Value::String.new(val[0].value)
434
+ end
435
+ .,.,
436
+
437
+ module_eval(<<'.,.,', 'kdl.yy', 52)
438
+ def _reduce_36(val, _values)
439
+ KDL::Value::Int.new(val[0].value)
440
+ end
441
+ .,.,
442
+
443
+ module_eval(<<'.,.,', 'kdl.yy', 53)
444
+ def _reduce_37(val, _values)
445
+ KDL::Value::Float.new(val[0].value, format: val[0].meta[:format])
446
+ end
447
+ .,.,
448
+
449
+ module_eval(<<'.,.,', 'kdl.yy', 54)
450
+ def _reduce_38(val, _values)
451
+ KDL::Value::Boolean.new(val[0])
452
+ end
453
+ .,.,
454
+
455
+ module_eval(<<'.,.,', 'kdl.yy', 55)
456
+ def _reduce_39(val, _values)
457
+ KDL::Value::Null
458
+ end
459
+ .,.,
460
+
461
+ module_eval(<<'.,.,', 'kdl.yy', 57)
462
+ def _reduce_40(val, _values)
463
+ true
464
+ end
465
+ .,.,
466
+
467
+ module_eval(<<'.,.,', 'kdl.yy', 58)
468
+ def _reduce_41(val, _values)
469
+ false
470
+ end
471
+ .,.,
472
+
473
+ # reduce 42 omitted
474
+
475
+ # reduce 43 omitted
476
+
477
+ # reduce 44 omitted
478
+
479
+ # reduce 45 omitted
480
+
481
+ # reduce 46 omitted
482
+
483
+ # reduce 47 omitted
484
+
485
+ # reduce 48 omitted
486
+
487
+ # reduce 49 omitted
488
+
489
+ # reduce 50 omitted
490
+
491
+ module_eval(<<'.,.,', 'kdl.yy', 65)
492
+ def _reduce_51(val, _values)
493
+ nil
494
+ end
495
+ .,.,
496
+
497
+ def _reduce_none(val, _values)
498
+ val[0]
499
+ end
500
+
501
+ end # class Parser
502
+ end # module KDL
data/lib/kdl/kdl.yy CHANGED
@@ -4,6 +4,7 @@ class KDL::Parser
4
4
  STRING RAWSTRING
5
5
  INTEGER FLOAT TRUE FALSE NULL
6
6
  WS NEWLINE
7
+ LBRACE RBRACE
7
8
  LPAREN RPAREN
8
9
  EQUALS
9
10
  SEMICOLON
@@ -13,37 +14,46 @@ rule
13
14
  document : nodes { KDL::Document.new(val[0]) }
14
15
  | linespaces { KDL::Document.new([])}
15
16
 
16
- nodes : none { [] }
17
- | linespace_star node { [val[1]] }
18
- | linespace_star empty_node { [] }
19
- | nodes node { [*val[0], val[1]] }
20
- | nodes empty_node { val[0] }
21
- node : node_decl node_term { val[0] }
22
- | node_decl node_children node_term { val[0].tap { |x| x.children = val[1] } }
23
- | node_decl empty_children node_term { val[0] }
24
- node_decl : identifier { KDL::Node.new(val[0]) }
25
- | node_decl WS value { val[0].tap { |x| x.arguments << val[2] } }
26
- | node_decl WS SLASHDASH ws_star value { val[0] }
27
- | node_decl WS property { val[0].tap { |x| x.properties[val[2][0]] = val[2][1] } }
28
- | node_decl WS SLASHDASH ws_star property { val[0] }
29
- empty_node: SLASHDASH ws_star node
30
- node_children: ws_star LPAREN nodes RPAREN { val[2] }
17
+ nodes : none { [] }
18
+ | linespace_star node { [val[1]] }
19
+ | linespace_star empty_node { [] }
20
+ | nodes node { [*val[0], val[1]] }
21
+ | nodes empty_node { val[0] }
22
+ node : untyped_node { val[0] }
23
+ | type untyped_node { val[1].as_type(val[0], @type_parsers.fetch(val[0], nil)) }
24
+ untyped_node : node_decl node_term { val[0].tap { |x| x.children = nil } }
25
+ | node_decl node_children node_term { val[0].tap { |x| x.children = val[1] } }
26
+ | node_decl empty_children node_term { val[0].tap { |x| x.children = nil } }
27
+ node_decl : identifier { KDL::Node.new(val[0]) }
28
+ | node_decl WS value { val[0].tap { |x| x.arguments << val[2] } }
29
+ | node_decl WS SLASHDASH ws_star value { val[0] }
30
+ | node_decl WS property { val[0].tap { |x| x.properties[val[2][0]] = val[2][1] } }
31
+ | node_decl WS SLASHDASH ws_star property { val[0] }
32
+ empty_node : SLASHDASH ws_star node
33
+ node_children : ws_star LBRACE nodes RBRACE { val[2] }
34
+ | ws_star LBRACE linespace_star RBRACE { [] }
31
35
  empty_children: SLASHDASH node_children
32
36
  | WS empty_children
33
37
  node_term: linespaces | semicolon_term
34
38
  semicolon_term: SEMICOLON | SEMICOLON linespaces
35
39
 
36
- identifier: IDENT { val[0] }
37
- | STRING { val[0] }
40
+ type : LPAREN identifier RPAREN { val[1] }
41
+
42
+ identifier: IDENT { val[0].value }
43
+ | STRING { val[0].value }
44
+ | RAWSTRING { val[0].value }
38
45
 
39
46
  property: identifier EQUALS value { [val[0], val[2]] }
40
47
 
41
- value : STRING { KDL::Value::String.new(val[0]) }
42
- | RAWSTRING { KDL::Value::String.new(val[0]) }
43
- | INTEGER { KDL::Value::Int.new(val[0]) }
44
- | FLOAT { KDL::Value::Float.new(val[0]) }
45
- | boolean { KDL::Value::Boolean.new(val[0]) }
46
- | NULL { KDL::Value::Null }
48
+ value : untyped_value
49
+ | type untyped_value { val[1].as_type(val[0], @type_parsers.fetch(val[0], nil)) }
50
+
51
+ untyped_value : STRING { KDL::Value::String.new(val[0].value) }
52
+ | RAWSTRING { KDL::Value::String.new(val[0].value) }
53
+ | INTEGER { KDL::Value::Int.new(val[0].value) }
54
+ | FLOAT { KDL::Value::Float.new(val[0].value, format: val[0].meta[:format]) }
55
+ | boolean { KDL::Value::Boolean.new(val[0]) }
56
+ | NULL { KDL::Value::Null }
47
57
 
48
58
  boolean : TRUE { true }
49
59
  | FALSE { false }
@@ -56,7 +66,13 @@ rule
56
66
  none: { nil }
57
67
 
58
68
  ---- inner
59
- def parse(str)
69
+
70
+ def parse(str, options = {})
71
+ if options.fetch(:parse_types, true)
72
+ @type_parsers = ::KDL::Types::MAPPING.merge(options.fetch(:type_parsers, {}))
73
+ else
74
+ @type_parsers = {}
75
+ end
60
76
  @tokenizer = ::KDL::Tokenizer.new(str)
61
77
  do_parse
62
78
  end
data/lib/kdl/node.rb CHANGED
@@ -1,31 +1,33 @@
1
1
  module KDL
2
2
  class Node
3
- attr_accessor :name, :arguments, :properties, :children
3
+ attr_accessor :name, :arguments, :properties, :children, :type
4
4
 
5
- def initialize(name, arguments = [], properties = {}, children = [])
5
+ def initialize(name, arguments = [], properties = {}, children = nil, type: nil)
6
6
  @name = name
7
7
  @arguments = arguments
8
8
  @properties = properties
9
9
  @children = children
10
+ @type = type
10
11
  end
11
12
 
12
13
  def to_s(level = 0)
13
14
  indent = ' ' * level
14
- s = "#{indent}#{name}"
15
+ s = "#{indent}#{type ? "(#{id_to_s type})" : ''}#{id_to_s name}"
15
16
  unless arguments.empty?
16
17
  s += " #{arguments.map(&:to_s).join(' ')}"
17
18
  end
18
19
  unless properties.empty?
19
- s += " #{properties.map { |k, v| "#{k}=#{v}" }.join(' ')}"
20
+ s += " #{properties.map { |k, v| "#{id_to_s k}=#{v}" }.join(' ')}"
20
21
  end
21
- unless children.empty?
22
+ unless children.nil?
22
23
  s += " {\n"
23
- s += children.map { |c| c.to_s(level + 1) }.join("\n")
24
- s += "\n#{indent}}"
24
+ unless children.empty?
25
+ s += children.map { |c| "#{c.to_s(level + 1)}\n" }.join("\n")
26
+ end
27
+ s += "#{indent}}"
25
28
  end
26
29
  s
27
30
  end
28
- alias inspect to_s
29
31
 
30
32
  def ==(other)
31
33
  return false unless other.is_a?(Node)
@@ -35,5 +37,28 @@ module KDL
35
37
  properties == other.properties &&
36
38
  children == other.children
37
39
  end
40
+
41
+ def as_type(type, parser = nil)
42
+ if parser.nil?
43
+ @type = type
44
+ self
45
+ else
46
+ result = parser.call(self, type)
47
+
48
+ return self.as_type(type) if result.nil?
49
+
50
+ unless result.is_a?(::KDL::Node)
51
+ raise ArgumentError, "expected parser to return an instance of ::KDL::Node, got `#{result.class}'"
52
+ end
53
+
54
+ result
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ def id_to_s(id)
61
+ StringDumper.stringify_identifier(id)
62
+ end
38
63
  end
39
64
  end
@@ -0,0 +1,45 @@
1
+ module KDL
2
+ module StringDumper
3
+ class << self
4
+ def call(string)
5
+ %("#{string.each_char.map { |char| escape(char) }.join}")
6
+ end
7
+
8
+ def stringify_identifier(ident)
9
+ if bare_identifier?(ident)
10
+ ident
11
+ else
12
+ call(ident)
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def print?(char)
19
+ ' ' <= char && char <= '\x7e'
20
+ end
21
+
22
+ def escape(char)
23
+ case char
24
+ when "\n" then '\n'
25
+ when "\r" then '\r'
26
+ when "\t" then '\t'
27
+ when '\\' then '\\\\'
28
+ when '"' then '\"'
29
+ when "\b" then '\b'
30
+ when "\f" then '\f'
31
+ else char
32
+ end
33
+ end
34
+
35
+ def unicode_escape(char)
36
+ "\\u{#{char.codepoints.first.to_s(16)}}"
37
+ end
38
+
39
+ def bare_identifier?(name)
40
+ escape_chars = '\\\/(){}<>;\[\]=,"'
41
+ name =~ /^([^0-9\-+\s#{escape_chars}][^\s#{escape_chars}]*|[\-+](?!true|false|null)[^0-9\s#{escape_chars}][^\s#{escape_chars}]*)$/
42
+ end
43
+ end
44
+ end
45
+ end