kdl 0.1.0 → 1.0.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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