source: pyyaml/trunk/lib/yaml/composer.py @ 223

Revision 223, 4.1 KB checked in by xi, 8 years ago (diff)

Completely rewrite the libyaml bindings.

Line 
1
2__all__ = ['Composer', 'ComposerError']
3
4from error import MarkedYAMLError
5from events import *
6from nodes import *
7
8class ComposerError(MarkedYAMLError):
9    pass
10
11class Composer(object):
12
13    def __init__(self):
14        self.anchors = {}
15
16    def check_node(self):
17        # If there are more documents available?
18        return not self.check_event(StreamEndEvent)
19
20    def get_node(self):
21        # Get the root node of the next document.
22        if not self.check_event(StreamEndEvent):
23            return self.compose_document()
24
25    def compose_document(self):
26
27        # Drop the STREAM-START event.
28        if self.check_event(StreamStartEvent):
29            self.get_event()
30
31        # Drop the DOCUMENT-START event.
32        self.get_event()
33
34        # Compose the root node.
35        node = self.compose_node(None, None)
36
37        # Drop the DOCUMENT-END event.
38        self.get_event()
39
40        self.anchors = {}
41        return node
42
43    def compose_node(self, parent, index):
44        if self.check_event(AliasEvent):
45            event = self.get_event()
46            anchor = event.anchor
47            if anchor not in self.anchors:
48                raise ComposerError(None, None, "found undefined alias %r"
49                        % anchor.encode('utf-8'), event.start_mark)
50            return self.anchors[anchor]
51        event = self.peek_event()
52        anchor = event.anchor
53        if anchor is not None:
54            if anchor in self.anchors:
55                raise ComposerError("found duplicate anchor %r; first occurence"
56                        % anchor.encode('utf-8'), self.anchors[anchor].start_mark,
57                        "second occurence", event.start_mark)
58        self.descend_resolver(parent, index)
59        if self.check_event(ScalarEvent):
60            node = self.compose_scalar_node(anchor)
61        elif self.check_event(SequenceStartEvent):
62            node = self.compose_sequence_node(anchor)
63        elif self.check_event(MappingStartEvent):
64            node = self.compose_mapping_node(anchor)
65        self.ascend_resolver()
66        return node
67
68    def compose_scalar_node(self, anchor):
69        event = self.get_event()
70        tag = event.tag
71        if tag is None or tag == u'!':
72            tag = self.resolve(ScalarNode, event.value, event.implicit)
73        node = ScalarNode(tag, event.value,
74                event.start_mark, event.end_mark, style=event.style)
75        if anchor is not None:
76            self.anchors[anchor] = node
77        return node
78
79    def compose_sequence_node(self, anchor):
80        start_event = self.get_event()
81        tag = start_event.tag
82        if tag is None or tag == u'!':
83            tag = self.resolve(SequenceNode, None, start_event.implicit)
84        node = SequenceNode(tag, [],
85                start_event.start_mark, None,
86                flow_style=start_event.flow_style)
87        if anchor is not None:
88            self.anchors[anchor] = node
89        index = 0
90        while not self.check_event(SequenceEndEvent):
91            node.value.append(self.compose_node(node, index))
92            index += 1
93        end_event = self.get_event()
94        node.end_mark = end_event.end_mark
95        return node
96
97    def compose_mapping_node(self, anchor):
98        start_event = self.get_event()
99        tag = start_event.tag
100        if tag is None or tag == u'!':
101            tag = self.resolve(MappingNode, None, start_event.implicit)
102        node = MappingNode(tag, [],
103                start_event.start_mark, None,
104                flow_style=start_event.flow_style)
105        if anchor is not None:
106            self.anchors[anchor] = node
107        while not self.check_event(MappingEndEvent):
108            #key_event = self.peek_event()
109            item_key = self.compose_node(node, None)
110            #if item_key in node.value:
111            #    raise ComposerError("while composing a mapping", start_event.start_mark,
112            #            "found duplicate key", key_event.start_mark)
113            item_value = self.compose_node(node, item_key)
114            #node.value[item_key] = item_value
115            node.value.append((item_key, item_value))
116        end_event = self.get_event()
117        node.end_mark = end_event.end_mark
118        return node
119
Note: See TracBrowser for help on using the repository browser.