2 require 'rbyaml/events'
6 class ComposerError < YAMLError
10 def initialize(parser,resolver)
17 !@parser.peek_event.__is_stream_end
21 compose_document if check_node
25 yield compose_document while check_node
29 # Drop the STREAM-START event.
30 @parser.get_event if @parser.peek_event.__is_stream_start
31 # Drop the DOCUMENT-START event.
33 # Compose the root node.
34 node = compose_node(nil,nil)
35 # Drop the DOCUMENT-END event.
41 def compose_node(parent,index)
42 if @parser.peek_event.__is_alias
43 event = @parser.get_event
45 raise ComposerError.new(nil, "found undefined alias #{anchor}") if !@anchors.include?(anchor)
46 return @anchors[anchor]
48 event = @parser.peek_event
51 if @anchors.include?(anchor)
52 raise ComposerError.new("found duplicate anchor #{anchor}; first occurence","second occurence")
55 @resolver.descend_resolver(parent,index)
56 if @parser.peek_event.__is_scalar
57 node = compose_scalar_node(anchor)
58 elsif @parser.peek_event.__is_sequence_start
59 node = compose_sequence_node(anchor)
60 elsif @parser.peek_event.__is_mapping_start
61 node = compose_mapping_node(anchor)
63 @resolver.ascend_resolver
67 def compose_scalar_node(anchor)
68 event = @parser.get_event
70 tag = @resolver.resolve(ScalarNode,event.value,event.implicit) if tag.nil? || tag == "!"
71 node = ScalarNode.new(tag, event.value,event.style)
72 @anchors[anchor] = node if !anchor.nil?
76 def compose_sequence_node(anchor)
77 start_event = @parser.get_event
79 tag = @resolver.resolve(SequenceNode,nil,start_event.implicit) if tag.nil? || tag == "!"
80 node = SequenceNode.new(tag,[],start_event.flow_style)
81 @anchors[anchor] = node if !anchor.nil?
83 while !@parser.peek_event.__is_sequence_end
84 node.value << compose_node(node,index)
91 def compose_mapping_node(anchor)
92 start_event = @parser.get_event
94 tag = @resolver.resolve(MappingNode,nil,start_event.implicit) if tag.nil? || tag == "!"
95 node = MappingNode.new(tag, {},start_event.flow_style)
96 @anchors[anchor] = node if !anchor.nil?
97 while !@parser.peek_event.__is_mapping_end
98 key_event = @parser.peek_event
99 item_key = compose_node(node,nil)
100 if node.value.include?(item_key)
101 raise ComposerError.new("while composing a mapping","found duplicate key")
103 item_value = compose_node(node,item_key)
104 node.value[item_key] = item_value