source: branches/pyyaml3000/lib/yaml/resolver.py @ 56

Revision 56, 4.7 KB checked in by xi, 9 years ago (diff)

Constructor is done.

Line 
1
2from nodes import *
3
4import re
5
6class BaseResolver:
7
8    DEFAULT_SCALAR_TAG = u'tag:yaml.org,2002:str'
9    DEFAULT_SEQUENCE_TAG = u'tag:yaml.org,2002:seq'
10    DEFAULT_MAPPING_TAG = u'tag:yaml.org,2002:map'
11
12    def __init__(self, composer):
13        self.composer = composer
14        self.resolved_nodes = {}
15
16    def check(self):
17        # If there are more documents available?
18        return self.composer.check()
19
20    def get(self):
21        # Resolve and return the root node of the next document.
22        if self.composer.check():
23            return self.resolve_document(self.composer.get())
24
25    def __iter__(self):
26        # Iterator protocol.
27        while self.composer.check():
28            yield self.resolve_document(self.composer.get())
29
30    def resolve_document(self, node):
31        self.resolve_node([], node)
32        return node
33        self.resolved_nodes = {}
34
35    def resolve_node(self, path, node):
36        if node in self.resolved_nodes:
37            return
38        self.resolved_nodes[node] = None
39        if isinstance(node, ScalarNode):
40            self.resolve_scalar(path, node)
41        elif isinstance(node, SequenceNode):
42            self.resolve_sequence(path, node)
43            for index in range(len(node.value)):
44                self.resolve_node(path+[(node, index)], node.value[index])
45        elif isinstance(node, MappingNode):
46            self.resolve_mapping(path, node)
47            for key in node.value:
48                self.resolve_node(path+[node, None], key)
49                self.resolve_node(path+[node, key], node.value[key])
50
51    def resolve_scalar(self, path, node):
52        if node.tag is None:
53            node.tag = self.detect_scalar(node.value)
54        if node.tag is None or node.tag == u'!':
55            node.tag = self.DEFAULT_SCALAR_TAG
56
57    def resolve_sequence(self, path, node):
58        if node.tag is None or node.tag == u'!':
59            node.tag = self.DEFAULT_SEQUENCE_TAG
60
61    def resolve_mapping(self, path, node):
62        if node.tag is None or node.tag == u'!':
63            node.tag = self.DEFAULT_MAPPING_TAG
64
65    def detect_scalar(self, value):
66        if value == u'':
67            detectors = self.yaml_detectors.get(u'', [])
68        else:
69            detectors = self.yaml_detectors.get(value[0], [])
70        detectors += self.yaml_detectors.get(None, [])
71        for tag, regexp in detectors:
72            if regexp.match(value):
73                return tag
74
75    def add_detector(cls, tag, regexp, first):
76        if not 'yaml_detectors' in cls.__dict__:
77            cls.yaml_detectors = cls.yaml_detectors.copy()
78        for ch in first:
79            cls.yaml_detectors.setdefault(ch, []).append((tag, regexp))
80    add_detector = classmethod(add_detector)
81
82    yaml_detectors = {}
83
84class Resolver(BaseResolver):
85    pass
86
87Resolver.add_detector(
88        u'tag:yaml.org,2002:bool',
89        re.compile(ur'''^(?:y|Y|yes|Yes|YES|n|N|no|No|NO
90                    |true|True|TRUE|false|False|FALSE
91                    |on|On|ON|off|Off|OFF)$''', re.X),
92        list(u'yYnNtTfFoO'))
93
94Resolver.add_detector(
95        u'tag:yaml.org,2002:float',
96        re.compile(ur'''^(?:[-+]?(?:[0-9][0-9_]*)?\.[0-9_]*(?:[eE][-+][0-9]+)?
97                    |[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\.[0-9_]*
98                    |[-+]?\.(?:inf|Inf|INF)
99                    |\.(?:nan|NaN|NAN))$''', re.X),
100        list(u'-+0123456789.'))
101
102Resolver.add_detector(
103        u'tag:yaml.org,2002:int',
104        re.compile(ur'''^(?:[-+]?0b[0-1_]+
105                    |[-+]?0[0-7_]+
106                    |[-+]?(?:0|[1-9][0-9_]*)
107                    |[-+]?0x[0-9a-fA-F_]+
108                    |[-+]?[1-9][0-9_]*(?::[0-5]?[0-9])+)$''', re.X),
109        list(u'-+0123456789'))
110
111Resolver.add_detector(
112        u'tag:yaml.org,2002:merge',
113        re.compile(ur'^(?:<<)$'),
114        ['<'])
115
116Resolver.add_detector(
117        u'tag:yaml.org,2002:null',
118        re.compile(ur'''^(?: ~
119                    |null|Null|NULL
120                    | )$''', re.X),
121        [u'~', u'n', u'N', u''])
122
123Resolver.add_detector(
124        u'tag:yaml.org,2002:timestamp',
125        re.compile(ur'''^(?:[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]
126                    |[0-9][0-9][0-9][0-9] -[0-9][0-9]? -[0-9][0-9]?
127                     (?:[Tt]|[ \t]+)[0-9][0-9]?
128                     :[0-9][0-9] :[0-9][0-9] (?:\.[0-9]*)?
129                     (?:[ \t]*(?:Z|[-+][0-9][0-9]?(?::[0-9][0-9])?))?)$''', re.X),
130        list(u'0123456789'))
131
132Resolver.add_detector(
133        u'tag:yaml.org,2002:value',
134        re.compile(ur'^(?:=)$'),
135        ['='])
136
137# The following detector is only for documentation purposes. It cannot work
138# because plain scalars cannot start with '!', '&', or '*'.
139Resolver.add_detector(
140        u'tag:yaml.org,2002:yaml',
141        re.compile(ur'^(?:!|&|\*)$'),
142        list(u'!&*'))
143
Note: See TracBrowser for help on using the repository browser.