source: branches/pyyaml3000/lib/yaml/composer.py @ 57

Revision 57, 3.6 KB checked in by xi, 8 years ago (diff)

Fix a few bugs.

RevLine 
[53]1
[57]2__all__ = ['Composer', 'ComposerError']
3
[53]4from error import MarkedYAMLError
5from events import *
6from nodes import *
7
8class ComposerError(MarkedYAMLError):
9    pass
10
11class Composer:
12
13    def __init__(self, parser):
14        self.parser = parser
15        self.all_anchors = {}
16        self.complete_anchors = {}
17
18    def check(self):
19        # If there are more documents available?
20        return not self.parser.check(StreamEndEvent)
21
22    def get(self):
23        # Get the root node of the next document.
24        if not self.parser.check(StreamEndEvent):
25            return self.compose_document()
26
27    def __iter__(self):
28        # Iterator protocol.
29        while not self.parser.check(StreamEndEvent):
30            yield self.compose_document()
31
32    def compose_document(self):
33        node = self.compose_node()
34        self.all_anchors = {}
35        self.complete_anchors = {}
36        return node
37
38    def compose_node(self):
39        if self.parser.check(AliasEvent):
40            event = self.parser.get()
41            anchor = event.anchor
42            if anchor not in self.all_anchors:
43                raise ComposerError(None, None, "found undefined alias %r"
44                        % anchor.encode('utf-8'), event.start_marker)
45            if anchor not in self.complete_anchors:
46                collection_event = self.all_anchors[anchor]
47                raise ComposerError("while composing a collection",
48                        collection_event.start_marker,
49                        "found recursive anchor %r" % anchor.encode('utf-8'),
50                        event.start_marker)
51            return self.complete_anchors[anchor]
52        event = self.parser.peek()
53        anchor = event.anchor
54        if anchor is not None:
55            if anchor in self.all_anchors:
56                raise ComposerError("found duplicate anchor %r; first occurence"
57                        % anchor.encode('utf-8'), self.all_anchors[anchor].start_marker,
58                        "second occurence", event.start_marker)
59            self.all_anchors[anchor] = event
60        if self.parser.check(ScalarEvent):
61            node = self.compose_scalar_node()
62        elif self.parser.check(SequenceEvent):
63            node = self.compose_sequence_node()
64        elif self.parser.check(MappingEvent):
65            node = self.compose_mapping_node()
66        if anchor is not None:
67            self.complete_anchors[anchor] = node
68        return node
69
70    def compose_scalar_node(self):
71        event = self.parser.get()
72        return ScalarNode(event.tag, event.value,
73                event.start_marker, event.end_marker)
74
75    def compose_sequence_node(self):
76        start_event = self.parser.get()
77        value = []
78        while not self.parser.check(CollectionEndEvent):
79            value.append(self.compose_node())
80        end_event = self.parser.get()
81        return SequenceNode(start_event.tag, value,
82                start_event.start_marker, end_event.end_marker)
83
84    def compose_mapping_node(self):
85        start_event = self.parser.get()
[55]86        value = {}
[53]87        while not self.parser.check(CollectionEndEvent):
[55]88            key_event = self.parser.peek()
[53]89            item_key = self.compose_node()
90            item_value = self.compose_node()
[55]91            if item_key in value:
92                raise ComposerError("while composing a mapping", start_event.start_marker,
93                        "found duplicate key", key_event.start_marker)
94            value[item_key] = item_value
[53]95        end_event = self.parser.get()
96        return MappingNode(start_event.tag, value,
97                start_event.start_marker, end_event.end_marker)
98
Note: See TracBrowser for help on using the repository browser.