RbYAML 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/README +1 -1
  2. data/lib/rbyaml/composer.rb +28 -25
  3. data/lib/rbyaml/composer.rb.~1.2.~ +109 -0
  4. data/lib/rbyaml/constructor.rb +94 -84
  5. data/lib/rbyaml/constructor.rb.~1.2.~ +381 -0
  6. data/lib/rbyaml/dumper.rb +10 -17
  7. data/lib/rbyaml/dumper.rb.~1.2.~ +43 -0
  8. data/lib/rbyaml/emitter.rb +13 -26
  9. data/lib/rbyaml/emitter.rb.~1.2.~ +1116 -0
  10. data/lib/rbyaml/error.rb +15 -21
  11. data/lib/rbyaml/events.rb +29 -5
  12. data/lib/rbyaml/events.rb.~1.2.~ +93 -0
  13. data/lib/rbyaml/loader.rb +11 -23
  14. data/lib/rbyaml/loader.rb.~1.2.~ +52 -0
  15. data/lib/rbyaml/nodes.rb +13 -9
  16. data/lib/rbyaml/nodes.rb.~1.2.~ +52 -0
  17. data/lib/rbyaml/parser.rb +481 -343
  18. data/lib/rbyaml/parser.rb.old +531 -0
  19. data/lib/rbyaml/parser.rb.~1.2.~ +494 -0
  20. data/lib/rbyaml/reader.rb.~1.1.1.1.~ +127 -0
  21. data/lib/rbyaml/representer.rb +26 -17
  22. data/lib/rbyaml/representer.rb.~1.2.~ +239 -0
  23. data/lib/rbyaml/resolver.rb +15 -15
  24. data/lib/rbyaml/resolver.rb.~1.1.~ +163 -0
  25. data/lib/rbyaml/scanner.rb +457 -366
  26. data/lib/rbyaml/scanner.rb.~1.2.~ +1259 -0
  27. data/lib/rbyaml/serializer.rb +19 -17
  28. data/lib/rbyaml/serializer.rb.~1.2.~ +115 -0
  29. data/lib/rbyaml/tokens.rb +44 -4
  30. data/lib/rbyaml/tokens.rb.~1.2.~ +164 -0
  31. data/lib/rbyaml/util.rb +28 -0
  32. data/lib/rbyaml/yaml.rb +12 -12
  33. data/lib/rbyaml/yaml.rb.~1.2.~ +136 -0
  34. data/test/test_bm.rb +28 -0
  35. data/test/test_bm_syck.rb +28 -0
  36. data/test/test_invoke.rb +31 -0
  37. data/test/test_one.rb +5 -0
  38. data/test/test_profile.rb +32 -0
  39. data/test/test_rbyaml.rb +2 -1
  40. data/test/test_rbyaml.rb.~1.2.~ +31 -0
  41. data/test/test_time.rb +13 -8
  42. data/test/test_time.rb.~1.1.~ +29 -0
  43. data/test/yamlx.rb +3563 -0
  44. metadata +27 -2
@@ -0,0 +1,494 @@
1
+
2
+ # YAML can be parsed by an LL(1) parser!
3
+ #
4
+ # We use the following production rules:
5
+ # stream ::= STREAM-START implicit_document? explicit_document* STREAM-END
6
+ # explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END?
7
+ # implicit_document ::= block_node DOCUMENT-END?
8
+ # block_node ::= ALIAS | properties? block_content
9
+ # flow_node ::= ALIAS | properties? flow_content
10
+ # properties ::= TAG ANCHOR? | ANCHOR TAG?
11
+ # block_content ::= block_collection | flow_collection | SCALAR
12
+ # flow_content ::= flow_collection | SCALAR
13
+ # block_collection ::= block_sequence | block_mapping
14
+ # block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
15
+ # block_mapping ::= BLOCK-MAPPING_START ((KEY block_node_or_indentless_sequence?)? (VALUE block_node_or_indentless_sequence?)?)* BLOCK-END
16
+ # block_node_or_indentless_sequence ::= ALIAS | properties? (block_content | indentless_block_sequence)
17
+ # indentless_block_sequence ::= (BLOCK-ENTRY block_node?)+
18
+ # flow_collection ::= flow_sequence | flow_mapping
19
+ # flow_sequence ::= FLOW-SEQUENCE-START (flow_sequence_entry FLOW-ENTRY)* flow_sequence_entry? FLOW-SEQUENCE-END
20
+ # flow_mapping ::= FLOW-MAPPING-START (flow_mapping_entry FLOW-ENTRY)* flow_mapping_entry? FLOW-MAPPING-END
21
+ # flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
22
+ # flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
23
+
24
+ # TODO: support for BOM within a stream.
25
+ # stream ::= (BOM? implicit_document)? (BOM? explicit_document)* STREAM-END
26
+
27
+ # FIRST sets:
28
+ # stream: { STREAM-START }
29
+ # explicit_document: { DIRECTIVE DOCUMENT-START }
30
+ # implicit_document: FIRST(block_node)
31
+ # block_node: { ALIAS TAG ANCHOR SCALAR BLOCK-SEQUENCE-START BLOCK-MAPPING-START FLOW-SEQUENCE-START FLOW-MAPPING-START }
32
+ # flow_node: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START FLOW-MAPPING-START }
33
+ # block_content: { BLOCK-SEQUENCE-START BLOCK-MAPPING-START FLOW-SEQUENCE-START FLOW-MAPPING-START SCALAR }
34
+ # flow_content: { FLOW-SEQUENCE-START FLOW-MAPPING-START SCALAR }
35
+ # block_collection: { BLOCK-SEQUENCE-START BLOCK-MAPPING-START }
36
+ # flow_collection: { FLOW-SEQUENCE-START FLOW-MAPPING-START }
37
+ # block_sequence: { BLOCK-SEQUENCE-START }
38
+ # block_mapping: { BLOCK-MAPPING-START }
39
+ # block_node_or_indentless_sequence: { ALIAS ANCHOR TAG SCALAR BLOCK-SEQUENCE-START BLOCK-MAPPING-START FLOW-SEQUENCE-START FLOW-MAPPING-START BLOCK-ENTRY }
40
+ # indentless_sequence: { ENTRY }
41
+ # flow_collection: { FLOW-SEQUENCE-START FLOW-MAPPING-START }
42
+ # flow_sequence: { FLOW-SEQUENCE-START }
43
+ # flow_mapping: { FLOW-MAPPING-START }
44
+ # flow_sequence_entry: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START FLOW-MAPPING-START KEY }
45
+ # flow_mapping_entry: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START FLOW-MAPPING-START KEY }
46
+
47
+ require 'rbyaml/error'
48
+ require 'rbyaml/tokens'
49
+ require 'rbyaml/events'
50
+ require 'rbyaml/scanner'
51
+
52
+ module RbYAML
53
+ class ParserError < MarkedYAMLError
54
+ end
55
+
56
+ module Parser
57
+
58
+ DEFAULT_TAGS = {
59
+ '!' => '!',
60
+ '!!' => 'tag:yaml.org,2002:'
61
+ }
62
+
63
+ def initialize_parser
64
+ @current_event = nil
65
+ @yaml_version = nil
66
+ @events = nil
67
+ @working_events = nil
68
+ @tag_handles = { }
69
+ end
70
+
71
+ def check_event(*choices)
72
+ init_events
73
+ @current_event = @working_events.shift if @current_event.nil?
74
+ if @current_event
75
+ return true if choices.empty?
76
+ for choice in choices
77
+ return true if choice === @current_event
78
+ end
79
+ end
80
+ false
81
+ end
82
+
83
+ def peek_event
84
+ init_events
85
+ @current_event = @working_events.shift if @current_event.nil?
86
+ @current_event
87
+ end
88
+
89
+ def get_event
90
+ init_events
91
+ @current_event = @working_events.shift if @current_event.nil?
92
+ value = @current_event
93
+ @current_event = nil
94
+ value
95
+ end
96
+
97
+ def init_events
98
+ @events ||= parse_stream
99
+ @working_events ||= @events
100
+ end
101
+
102
+ def each_event(&block)
103
+ init_events
104
+ @events.each(&block)
105
+ end
106
+
107
+ def parse_stream
108
+ # STREAM-START implicit_document? explicit_document* STREAM-END
109
+
110
+ # Parse start of stream.
111
+ events = []
112
+ token = get_token
113
+ events << StreamStartEvent.new(token.start_mark, token.end_mark,token.encoding)
114
+
115
+ # Parse implicit document.
116
+ unless check_token(DirectiveToken, DocumentStartToken,StreamEndToken)
117
+ @tag_handles = DEFAULT_TAGS
118
+ token = peek_token
119
+ start_mark = end_mark = token.start_mark
120
+ events << DocumentStartEvent.new(start_mark, end_mark,false)
121
+ events += parse_block_node
122
+ token = peek_token
123
+ start_mark = end_mark = token.start_mark
124
+ explicit = false
125
+ while check_token(DocumentEndToken)
126
+ token = get_token
127
+ end_mark = token.end_mark
128
+ explicit = true
129
+ end
130
+ events << DocumentEndEvent.new(start_mark, end_mark,explicit)
131
+ end
132
+
133
+ # Parse explicit documents.
134
+ while !check_token(StreamEndToken)
135
+ token = peek_token
136
+ start_mark = token.start_mark
137
+ version, tags = process_directives
138
+ raise ParserError.new(nil, nil,"expected '<document start>', but found #{peek_token.id}",peek_token.start_mark) unless check_token(DocumentStartToken)
139
+ token = get_token
140
+ end_mark = token.end_mark
141
+ events << DocumentStartEvent.new(start_mark, end_mark,true,version,tags)
142
+ if check_token(DirectiveToken,DocumentStartToken, DocumentEndToken, StreamEndToken)
143
+ events << process_empty_scalar(token.end_mark)
144
+ else
145
+ events += parse_block_node
146
+ end
147
+ token = peek_token
148
+ start_mark = end_mark = token.start_mark
149
+ explicit = false
150
+ while check_token(DocumentEndToken)
151
+ token = get_token
152
+ end_mark = token.end_mark
153
+ explicit=true
154
+ end
155
+ events << DocumentEndEvent.new(start_mark, end_mark,explicit)
156
+ end
157
+ # Parse end of stream.
158
+ token = get_token
159
+ events << StreamEndEvent.new(token.start_mark, token.end_mark)
160
+ events
161
+ end
162
+
163
+ def process_directives
164
+ # DIRECTIVE*
165
+ while check_token(DirectiveToken)
166
+ token = get_token
167
+ if token.name == "YAML"
168
+ raise ParserError.new(nil, nil,"found duplicate YAML directive", token.start_mark) if !@yaml_version.nil?
169
+ major, minor = token.value[0].to_i, token.value[1].to_i
170
+ raise ParserError.new(nil,nil,"found incompatible YAML document (version 1.* is required)",token.start_mark) if major != 1
171
+ @yaml_version = [major,minor]
172
+ elsif token.name == "TAG"
173
+ handle, prefix = token.value
174
+ raise ParserError.new(nil,nil,"duplicate tag handle #{handle}",token.start_mark) if @tag_handles.member?(handle)
175
+ @tag_handles[handle] = prefix
176
+ end
177
+ end
178
+ if !@tag_handles.empty?
179
+ value = @yaml_version, @tag_handles.dup
180
+ else
181
+ value = @yaml_version, nil
182
+ end
183
+ for key in DEFAULT_TAGS.keys
184
+ @tag_handles[key] = DEFAULT_TAGS[key] if !@tag_handles.include?(key)
185
+ end
186
+ value
187
+ end
188
+
189
+ def parse_block_node
190
+ parse_node(true)
191
+ end
192
+
193
+ def parse_flow_node
194
+ parse_node
195
+ end
196
+
197
+ def parse_block_node_or_indentless_sequence
198
+ parse_node(true, true)
199
+ end
200
+
201
+ def parse_node(block=false, indentless_sequence=false)
202
+ # block_node ::= ALIAS | properties? block_content
203
+ # flow_node ::= ALIAS | properties? flow_content
204
+ # properties ::= TAG ANCHOR? | ANCHOR TAG?
205
+ # block_content ::= block_collection | flow_collection | SCALAR
206
+ # flow_content ::= flow_collection | SCALAR
207
+ # block_collection ::= block_sequence | block_mapping
208
+ # block_node_or_indentless_sequence ::= ALIAS | properties?
209
+ # (block_content | indentless_block_sequence)
210
+ events = []
211
+ if check_token(AliasToken)
212
+ token = get_token
213
+ events << AliasEvent.new(token.value, token.start_mark, token.end_mark)
214
+ else
215
+ anchor = nil
216
+ tag = nil
217
+ start_mark = end_mark = tag_mark = nil
218
+ if check_token(AnchorToken)
219
+ token = get_token
220
+ start_mark = token.start_mark
221
+ end_mark = token.end_mark
222
+ anchor = token.value
223
+ if check_token(TagToken)
224
+ token = get_token
225
+ tag_mark = token.start_mark
226
+ end_mark = token.end_mark
227
+ tag = token.value
228
+ end
229
+ elsif check_token(TagToken)
230
+ token = get_token
231
+ start_mark = tag_mark = token.start_mark
232
+ end_mark = token.end_mark
233
+ tag = token.value
234
+ if check_token(AnchorToken)
235
+ token = get_token
236
+ end_mark = token.end_mark
237
+ anchor = token.value
238
+ end
239
+ end
240
+
241
+ if !tag.nil? and tag != "!"
242
+ handle, suffix = tag
243
+ if !handle.nil?
244
+ raise ParserError.new("while parsing a node", start_mark,"found undefined tag handle #{handle}",tag_mark) if !@tag_handles.include?(handle)
245
+ tag = @tag_handles[handle]+suffix
246
+ else
247
+ tag = suffix
248
+ end
249
+ end
250
+
251
+ #if tag == u'!':
252
+ # raise ParserError("while parsing a node", start_mark,
253
+ # "found non-specific tag '!'", tag_mark,
254
+ # "Please check 'http://pyyaml.org/wiki/YAMLNonSpecificTag' and share your opinion.")
255
+ if start_mark.nil?
256
+ start_mark = end_mark = peek_token.start_mark
257
+ end
258
+ event = nil
259
+ collection_events = nil
260
+ implicit = tag.nil? || tag == ?!
261
+ if indentless_sequence && check_token(BlockEntryToken)
262
+ end_mark = peek_token.end_mark
263
+ event = SequenceStartEvent.new(anchor, tag, implicit, start_mark, end_mark)
264
+ collection_events = parse_indentless_sequence
265
+ else
266
+ if check_token(ScalarToken)
267
+ token = get_token
268
+ end_mark = token.end_mark
269
+ if (token.plain && tag.nil?) || tag == ?!
270
+ implicit = [true, false]
271
+ elsif tag.nil?
272
+ implicit = [false, true]
273
+ else
274
+ implicit = [false, false]
275
+ end
276
+ event = ScalarEvent.new(anchor, tag, implicit, token.value,start_mark, end_mark,token.style)
277
+ elsif check_token(FlowSequenceStartToken)
278
+ end_mark = peek_token.end_mark
279
+ event = SequenceStartEvent.new(anchor, tag, implicit, start_mark, end_mark,true)
280
+ collection_events = parse_flow_sequence
281
+ elsif check_token(FlowMappingStartToken)
282
+ end_mark = peek_token.end_mark
283
+ event = MappingStartEvent.new(anchor, tag, implicit, start_mark, end_mark,true)
284
+ collection_events = parse_flow_mapping
285
+ elsif block && check_token(BlockSequenceStartToken)
286
+ end_mark = peek_token.start_mark
287
+ event = SequenceStartEvent.new(anchor, tag, implicit, start_mark, end_mark,false)
288
+ collection_events = parse_block_sequence
289
+ elsif block && check_token(BlockMappingStartToken)
290
+ end_mark = peek_token.start_mark
291
+ event = MappingStartEvent.new(anchor, tag, implicit, start_mark, end_mark,false)
292
+ collection_events = parse_block_mapping
293
+ elsif !anchor.nil? || !tag.nil?
294
+ # Empty scalars are allowed even if a tag or an anchor is
295
+ # specified.
296
+ event = ScalarEvent.new(anchor, tag, [implicit,false],"",start_mark, end_mark)
297
+ else
298
+ if block
299
+ node = "block"
300
+ else
301
+ node = "flow"
302
+ end
303
+ token = peek_token
304
+ raise ParserError.new("while scanning a #{node} node", start_mark,"expected the node content, but found #{token.tid}",token.start_mark)
305
+ end
306
+ end
307
+ events << event
308
+ events += collection_events if collection_events
309
+ end
310
+ events
311
+ end
312
+
313
+ def parse_block_sequence
314
+ # BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
315
+ events = []
316
+ token = get_token
317
+ start_mark = token.start_mark
318
+ while check_token(BlockEntryToken)
319
+ token = get_token
320
+ if !check_token(BlockEntryToken, BlockEndToken)
321
+ events += parse_block_node
322
+ else
323
+ events << process_empty_scalar(token.end_mark)
324
+ end
325
+ end
326
+ if !check_token(BlockEndToken)
327
+ token = peek_token
328
+ raise ParserError.new("while scanning a block collection", start_mark,"expected <block end>, but found #{token.tid}", token.start_mark)
329
+ end
330
+ token = get_token
331
+ events << SequenceEndEvent.new(token.start_mark, token.end_mark)
332
+ events
333
+ end
334
+
335
+ def parse_indentless_sequence
336
+ # (BLOCK-ENTRY block_node?)+
337
+ events = []
338
+ while check_token(BlockEntryToken)
339
+ token = get_token
340
+ if !check_token(BlockEntryToken,KeyToken, ValueToken, BlockEndToken)
341
+ events += parse_block_node
342
+ else
343
+ events << process_empty_scalar(token.end_mark)
344
+ end
345
+ end
346
+ token = peek_token
347
+ events << SequenceEndEvent.new(token.start_mark, token.start_mark)
348
+ events
349
+ end
350
+
351
+
352
+ def parse_block_mapping
353
+ # BLOCK-MAPPING_START
354
+ # ((KEY block_node_or_indentless_sequence?)?
355
+ # (VALUE block_node_or_indentless_sequence?)?)*
356
+ # BLOCK-END
357
+ events = []
358
+ token = get_token
359
+ start_mark = token.start_mark
360
+ while check_token(KeyToken, ValueToken)
361
+ if check_token(KeyToken)
362
+ token = get_token
363
+ if !check_token(KeyToken, ValueToken, BlockEndToken)
364
+ events += parse_block_node_or_indentless_sequence
365
+ else
366
+ events << process_empty_scalar(token.end_mark)
367
+ end
368
+ end
369
+ if check_token(ValueToken)
370
+ token = get_token
371
+ if !check_token(KeyToken, ValueToken, BlockEndToken)
372
+ events += parse_block_node_or_indentless_sequence
373
+ else
374
+ events << process_empty_scalar(token.end_mark)
375
+ end
376
+ else
377
+ token = peek_token
378
+ events << process_empty_scalar(token.start_mark)
379
+ end
380
+ end
381
+ if !check_token(BlockEndToken)
382
+ token = peek_token
383
+ raise ParserError.new("while scanning a block mapping", start_mark,"expected <block end>, but found #{token.tid}", token.start_mark)
384
+ end
385
+ token = get_token
386
+ events << MappingEndEvent.new(token.start_mark, token.end_mark)
387
+ events
388
+ end
389
+
390
+ def parse_flow_sequence
391
+ # flow_sequence ::= FLOW-SEQUENCE-START
392
+ # (flow_sequence_entry FLOW-ENTRY)*
393
+ # flow_sequence_entry?
394
+ # FLOW-SEQUENCE-END
395
+ # flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
396
+ #
397
+ # Note that while production rules for both flow_sequence_entry and
398
+ # flow_mapping_entry are equal, their interpretations are different.
399
+ # For `flow_sequence_entry`, the part `KEY flow_node? (VALUE flow_node?)?`
400
+ # generate an inline mapping (set syntax).
401
+ events = []
402
+ token = get_token
403
+ start_mark = token.start_mark
404
+ while !check_token(FlowSequenceEndToken)
405
+ if check_token(KeyToken)
406
+ token = get_token
407
+ events << MappingStartEvent.new(nil,nil,true,token.start_mark, token.end_mark,true)
408
+ if !check_token(ValueToken,FlowEntryToken, FlowSequenceEndToken)
409
+ events += parse_flow_node
410
+ else
411
+ events << process_empty_scalar(token.end_mark)
412
+ end
413
+ if check_token(ValueToken)
414
+ token = get_token
415
+ if !check_token(FlowEntryToken, FlowSequenceEndToken)
416
+ events += parse_flow_node
417
+ else
418
+ events << process_empty_scalar(token.end_mark)
419
+ end
420
+ else
421
+ token = peek_token
422
+ events << process_empty_scalar(token.start_mark)
423
+ end
424
+ token = peek_token
425
+ events << MappingEndEvent.new(token.start_mark, token.start_mark)
426
+ else
427
+ events += parse_flow_node
428
+ end
429
+ if !check_token(FlowEntryToken, FlowSequenceEndToken)
430
+ token = peek_token
431
+ raise ParserError.new("while scanning a flow sequence", start_mark,"expected ',' or ']', but got #{token.tid}", token.start_mark)
432
+ end
433
+ if check_token(FlowEntryToken)
434
+ get_token
435
+ end
436
+ end
437
+ token = get_token
438
+ events << SequenceEndEvent.new(token.start_mark, token.end_mark)
439
+ events
440
+ end
441
+
442
+ def parse_flow_mapping
443
+ # flow_mapping ::= FLOW-MAPPING-START
444
+ # (flow_mapping_entry FLOW-ENTRY)*
445
+ # flow_mapping_entry?
446
+ # FLOW-MAPPING-END
447
+ # flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
448
+ events = []
449
+ token = get_token
450
+ start_mark = token.start_mark
451
+ while !check_token(FlowMappingEndToken)
452
+ if check_token(KeyToken)
453
+ token = get_token
454
+ if !check_token(ValueToken,FlowEntryToken, FlowMappingEndToken)
455
+ events += parse_flow_node
456
+ else
457
+ events << process_empty_scalar(token.end_mark)
458
+ end
459
+ if check_token(ValueToken)
460
+ token = get_token
461
+ if !check_token(FlowEntryToken, FlowMappingEndToken)
462
+ events += parse_flow_node
463
+ else
464
+ events << process_empty_scalar(token.end_mark)
465
+ end
466
+ else
467
+ token = peek_token
468
+ events << process_empty_scalar(token.start_mark)
469
+ end
470
+ else
471
+ events += parse_flow_node
472
+ events << process_empty_scalar(peek_token.start_mark)
473
+ end
474
+ if !check_token(FlowEntryToken, FlowMappingEndToken)
475
+ token = peek_token
476
+ raise ParserError.new("while scanning a flow mapping", start_mark,"expected ',' or '}', but got #{token.tid}", token.start_mark)
477
+ end
478
+ get_token if check_token(FlowEntryToken)
479
+ end
480
+ if !check_token(FlowMappingEndToken)
481
+ token = peek_token
482
+ raise ParserError.new("while scanning a flow mapping", start_mark,"expected '}', but found #{token.tid}", token.start_mark)
483
+ end
484
+ token = get_token
485
+ events << MappingEndEvent.new(token.start_mark, token.end_mark)
486
+ events
487
+ end
488
+
489
+ def process_empty_scalar(mark)
490
+ ScalarEvent.new(nil, nil, [true, false], "", mark, mark)
491
+ end
492
+ end
493
+ end
494
+