Ignore:
Timestamp:
04/15/06 19:54:52 (9 years ago)
Author:
xi
Message:

Major refactoring.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pyyaml/trunk/lib/yaml/composer.py

    r133 r136  
    11 
    2 __all__ = ['Composer', 'ComposerError'] 
     2__all__ = ['BaseComposer', 'Composer', 'ComposerError'] 
    33 
    44from error import MarkedYAMLError 
     
    99    pass 
    1010 
    11 class Composer: 
     11class BaseComposer: 
    1212 
    13     def __init__(self, parser): 
    14         self.parser = parser 
     13    yaml_resolvers = {} 
     14 
     15    def __init__(self): 
    1516        self.all_anchors = {} 
    1617        self.complete_anchors = {} 
     18        self.resolver_tags = [] 
     19        self.resolver_paths = [] 
    1720 
    18         # Drop the STREAM-START event. 
    19         self.parser.get() 
     21    def check_node(self): 
     22        # If there are more documents available? 
     23        return not self.check_event(StreamEndEvent) 
    2024 
    21     def check(self): 
    22         # If there are more documents available? 
    23         return not self.parser.check(StreamEndEvent) 
    24  
    25     def get(self): 
     25    def get_node(self): 
    2626        # Get the root node of the next document. 
    27         if not self.parser.check(StreamEndEvent): 
     27        if not self.check_event(StreamEndEvent): 
    2828            return self.compose_document() 
    2929 
    3030    def __iter__(self): 
    3131        # Iterator protocol. 
    32         while not self.parser.check(StreamEndEvent): 
     32        while not self.check_event(StreamEndEvent): 
    3333            yield self.compose_document() 
    3434 
    3535    def compose_document(self): 
    3636 
     37        # Drop the STREAM-START event. 
     38        if self.check_event(StreamStartEvent): 
     39            self.get_event() 
     40 
    3741        # Drop the DOCUMENT-START event. 
    38         self.parser.get() 
     42        self.get_event() 
    3943 
    4044        # Compose the root node. 
    41         node = self.compose_node() 
     45        node = self.compose_node([]) 
    4246 
    4347        # Drop the DOCUMENT-END event. 
    44         self.parser.get() 
     48        self.get_event() 
    4549 
    4650        self.all_anchors = {} 
    4751        self.complete_anchors = {} 
     52        self.resolver_tags = [] 
     53        self.resolver_paths = [] 
    4854        return node 
    4955 
    50     def compose_node(self): 
    51         if self.parser.check(AliasEvent): 
    52             event = self.parser.get() 
     56    def increase_resolver_depth(self, path): 
     57        depth = len(path) 
     58        tag = None 
     59        paths = [] 
     60        if not depth: 
     61            for resolver_path in self.yaml_resolvers.keys(): 
     62                if resolver_path: 
     63                    paths.append(resolver_path) 
     64                else: 
     65                    tag = self.yaml_resolvers[resolver_path] 
     66        else: 
     67            base, index = path[-1] 
     68            if isinstance(index, ScalarNode)    \ 
     69                    and index.tag == self.DEFAULT_SCALAR_TAG: 
     70                index = index.value 
     71            elif isinstance(index, Node): 
     72                index = None 
     73            for resolver_path in self.resolver_paths[-1]: 
     74                resolver_index = resolver_path[depth-1] 
     75                if resolver_index is None or resolver_index == index: 
     76                    if len(resolver_index) > depth: 
     77                        paths.append(resolver_path) 
     78                    else: 
     79                        tag = self.yaml_resolvers[resolver_path] 
     80        self.resolver_tags.append(tag) 
     81        self.resolver_paths.append(paths) 
     82 
     83    def decrease_resolver_depth(self): 
     84        del self.resolver_tags[-1] 
     85        del self.resolver_paths[-1] 
     86 
     87    def compose_node(self, path): 
     88        if self.check_event(AliasEvent): 
     89            event = self.get_event() 
    5390            anchor = event.anchor 
    5491            if anchor not in self.all_anchors: 
     
    6299                        event.start_mark) 
    63100            return self.complete_anchors[anchor] 
    64         event = self.parser.peek() 
     101        self.increase_resolver_depth(path) 
     102        event = self.peek_event() 
    65103        anchor = event.anchor 
    66104        if anchor is not None: 
     
    70108                        "second occurence", event.start_mark) 
    71109            self.all_anchors[anchor] = event 
    72         if self.parser.check(ScalarEvent): 
    73             node = self.compose_scalar_node() 
    74         elif self.parser.check(SequenceStartEvent): 
    75             node = self.compose_sequence_node() 
    76         elif self.parser.check(MappingStartEvent): 
    77             node = self.compose_mapping_node() 
     110        if self.check_event(ScalarEvent): 
     111            node = self.compose_scalar_node(path) 
     112        elif self.check_event(SequenceStartEvent): 
     113            node = self.compose_sequence_node(path) 
     114        elif self.check_event(MappingStartEvent): 
     115            node = self.compose_mapping_node(path) 
    78116        if anchor is not None: 
    79117            self.complete_anchors[anchor] = node 
     118        self.decrease_resolver_depth() 
    80119        return node 
    81120 
    82     def compose_scalar_node(self): 
    83         event = self.parser.get() 
    84         return ScalarNode(event.tag, event.value, event.implicit, 
     121    def compose_scalar_node(self, path): 
     122        event = self.get_event() 
     123        tag = self.resolve_scalar(path, event.tag, event.implicit, event.value) 
     124        return ScalarNode(tag, event.value, 
    85125                event.start_mark, event.end_mark, style=event.style) 
    86126 
    87     def compose_sequence_node(self): 
    88         start_event = self.parser.get() 
    89         value = [] 
    90         while not self.parser.check(SequenceEndEvent): 
    91             value.append(self.compose_node()) 
    92         end_event = self.parser.get() 
    93         return SequenceNode(start_event.tag, value, 
    94                 start_event.start_mark, end_event.end_mark, 
     127    def compose_sequence_node(self, path): 
     128        start_event = self.get_event() 
     129        tag = self.resolve_sequence(path, start_event.tag) 
     130        node = SequenceNode(tag, [], 
     131                start_event.start_mark, None, 
    95132                flow_style=start_event.flow_style) 
     133        index = 0 
     134        while not self.check_event(SequenceEndEvent): 
     135            node.value.append(self.compose_node(path+[(node, index)])) 
     136            index += 1 
     137        end_event = self.get_event() 
     138        node.end_mark = end_event.end_mark 
     139        return node 
    96140 
    97     def compose_mapping_node(self): 
    98         start_event = self.parser.get() 
    99         value = {} 
    100         while not self.parser.check(MappingEndEvent): 
    101             key_event = self.parser.peek() 
    102             item_key = self.compose_node() 
    103             item_value = self.compose_node() 
    104             if item_key in value: 
     141    def compose_mapping_node(self, path): 
     142        start_event = self.get_event() 
     143        tag = self.resolve_mapping(path, start_event.tag) 
     144        node = MappingNode(tag, {}, 
     145                start_event.start_mark, None, 
     146                flow_style=start_event.flow_style) 
     147        while not self.check_event(MappingEndEvent): 
     148            key_event = self.peek_event() 
     149            item_key = self.compose_node(path+[(node, None)]) 
     150            item_value = self.compose_node(path+[(node, item_key)]) 
     151            if item_key in node.value: 
    105152                raise ComposerError("while composing a mapping", start_event.start_mark, 
    106153                        "found duplicate key", key_event.start_mark) 
    107             value[item_key] = item_value 
    108         end_event = self.parser.get() 
    109         return MappingNode(start_event.tag, value, 
    110                 start_event.start_mark, end_event.end_mark, 
    111                 flow_style=start_event.flow_style) 
     154            node.value[item_key] = item_value 
     155        end_event = self.get_event() 
     156        node.end_mark = end_event.end_mark 
     157        return node 
    112158 
     159    def resolve_scalar(self, path, tag, implicit, value): 
     160        if implicit: 
     161            tag = self.detect(value) 
     162        if tag is None and self.resolver_tags[-1]: 
     163            tag = self.resolver_tags[-1] 
     164        if tag is None or tag == u'!': 
     165            tag = self.DEFAULT_SCALAR_TAG 
     166        return tag 
     167 
     168    def resolve_sequence(self, path, tag): 
     169        if tag is None and self.resolver_tags[-1]: 
     170            tag = self.resolver_tags[-1] 
     171        if tag is None or tag == u'!': 
     172            tag = self.DEFAULT_SEQUENCE_TAG 
     173        return tag 
     174 
     175    def resolve_mapping(self, path, tag): 
     176        if tag is None and self.resolver_tags[-1]: 
     177            tag = self.resolver_tags[-1] 
     178        if tag is None or tag == u'!': 
     179            tag = self.DEFAULT_MAPPING_TAG 
     180        return tag 
     181 
     182    def add_resolver(self, tag, path): 
     183        if not 'yaml_resolvers' in cls.__dict__: 
     184            cls.yaml_resolvers = cls.yaml_resolvers.copy() 
     185        cls.yaml_resolvers[tuple(path)] = tag 
     186    add_resolver = classmethod(add_resolver) 
     187 
     188class Composer(BaseComposer): 
     189    pass 
     190 
Note: See TracChangeset for help on using the changeset viewer.