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

Revision 55, 3.5 KB checked in by xi, 8 years ago (diff)

Working on Constructor.

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