Rosetta
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
composer.py
Go to the documentation of this file.
1 # (c) Copyright Rosetta Commons Member Institutions.
2 # (c) This file is part of the Rosetta software suite and is made available under license.
3 # (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
4 # (c) For more information, see http://www.rosettacommons.org. Questions about this can be
5 # (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
6 
7 __all__ = ['Composer', 'ComposerError']
8 
9 from error import MarkedYAMLError
10 from events import *
11 from nodes import *
12 
13 class ComposerError(MarkedYAMLError):
14  pass
15 
16 class Composer(object):
17 
18  def __init__(self):
19  self.anchors = {}
20 
21  def check_node(self):
22  # Drop the STREAM-START event.
23  if self.check_event(StreamStartEvent):
24  self.get_event()
25 
26  # If there are more documents available?
27  return not self.check_event(StreamEndEvent)
28 
29  def get_node(self):
30  # Get the root node of the next document.
31  if not self.check_event(StreamEndEvent):
32  return self.compose_document()
33 
34  def compose_document(self):
35  # Drop the DOCUMENT-START event.
36  self.get_event()
37 
38  # Compose the root node.
39  node = self.compose_node(None, None)
40 
41  # Drop the DOCUMENT-END event.
42  self.get_event()
43 
44  self.anchors = {}
45  return node
46 
47  def compose_node(self, parent, index):
48  if self.check_event(AliasEvent):
49  event = self.get_event()
50  anchor = event.anchor
51  if anchor not in self.anchors:
52  raise ComposerError(None, None, "found undefined alias %r"
53  % anchor.encode('utf-8'), event.start_mark)
54  return self.anchors[anchor]
55  event = self.peek_event()
56  anchor = event.anchor
57  if anchor is not None:
58  if anchor in self.anchors:
59  raise ComposerError("found duplicate anchor %r; first occurence"
60  % anchor.encode('utf-8'), self.anchors[anchor].start_mark,
61  "second occurence", event.start_mark)
62  self.descend_resolver(parent, index)
63  if self.check_event(ScalarEvent):
64  node = self.compose_scalar_node(anchor)
65  elif self.check_event(SequenceStartEvent):
66  node = self.compose_sequence_node(anchor)
67  elif self.check_event(MappingStartEvent):
68  node = self.compose_mapping_node(anchor)
69  self.ascend_resolver()
70  return node
71 
72  def compose_scalar_node(self, anchor):
73  event = self.get_event()
74  tag = event.tag
75  if tag is None or tag == u'!':
76  tag = self.resolve(ScalarNode, event.value, event.implicit)
77  node = ScalarNode(tag, event.value,
78  event.start_mark, event.end_mark, style=event.style)
79  if anchor is not None:
80  self.anchors[anchor] = node
81  return node
82 
83  def compose_sequence_node(self, anchor):
84  start_event = self.get_event()
85  tag = start_event.tag
86  if tag is None or tag == u'!':
87  tag = self.resolve(SequenceNode, None, start_event.implicit)
88  node = SequenceNode(tag, [],
89  start_event.start_mark, None,
90  flow_style=start_event.flow_style)
91  if anchor is not None:
92  self.anchors[anchor] = node
93  index = 0
94  while not self.check_event(SequenceEndEvent):
95  node.value.append(self.compose_node(node, index))
96  index += 1
97  end_event = self.get_event()
98  node.end_mark = end_event.end_mark
99  return node
100 
101  def compose_mapping_node(self, anchor):
102  start_event = self.get_event()
103  tag = start_event.tag
104  if tag is None or tag == u'!':
105  tag = self.resolve(MappingNode, None, start_event.implicit)
106  node = MappingNode(tag, [],
107  start_event.start_mark, None,
108  flow_style=start_event.flow_style)
109  if anchor is not None:
110  self.anchors[anchor] = node
111  while not self.check_event(MappingEndEvent):
112  #key_event = self.peek_event()
113  item_key = self.compose_node(node, None)
114  #if item_key in node.value:
115  # raise ComposerError("while composing a mapping", start_event.start_mark,
116  # "found duplicate key", key_event.start_mark)
117  item_value = self.compose_node(node, item_key)
118  #node.value[item_key] = item_value
119  node.value.append((item_key, item_value))
120  end_event = self.get_event()
121  node.end_mark = end_event.end_mark
122  return node
123