|
Package hm ::
Package app ::
Package lib ::
Module patterns
|
|
1
2 import re
3 from structures import *
4
5
6
7
8
9
10 -def chain_s(pattern, separator='none', next='next', rest='rest',
11 allow_dangle=True, allow_blank=True):
12 p = PID(p="%("+pattern+")s",
13 s="%("+separator+")s",
14 dangle='', blank='|', next=next, rest=rest)
15 if allow_dangle: p['dangle'] = r'(?:%(s)s)?' % p
16 if not allow_blank: p['blank'] = ''
17 return r'(?:%(p)s(?:%(s)s(?:%(p)s%(s)s)*%(p)s)?%(dangle)s%(blank)s)' % p
18
19
20
22 p = PID(p="%("+pattern+")s",
23 p_n="%("+pattern+"_n)s",
24 s="%("+separator+")s")
25 return r'(?:(?P<next>%(p_n)s)(?:%(s)s)?)' % p
26
27
28
29 BLANK_RE = r''
30 UNMATCHABLE_RE = r'$^'
31
32
33
34
37 return self.get(key, "%("+str(key)+")s")
38 PID = PartialInterpolationDict
39
40
41
44 if not hasattr(self, 'count_'):
45 self.count_ = 0
46 else:
47 self.count_ += 1
48
49 return self.get(key, UNMATCHABLE_RE)
50 Fid = FinalInterpolationDict()
51
52
53
55 """Combine multiple mappings for sequential lookup. Raymond Hettinger,
56 http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/305268 """
59 - def get(self, key, default):
60 try:
61 return self[key]
62 except KeyError:
63 return default
65 for mapping in self._maps:
66 try:
67 return mapping[key]
68 except KeyError:
69 pass
70 raise KeyError(key)
72 ret = {}
73 [ret.update(mapping) for mapping in self._maps]
74 return ret.items()
75
76
77 DEFAULT_DEPTH = 14
78
93
94
95 BASE_PATTERNS = {
96 'none' : r'',
97 'space?': r'\s*',
98 'space' : r'\s+',
99
100
101 'comma' : r'(?:\s*,\s*)',
102 'equal' : r'(?:\s*=\s*)',
103 'bar' : r'(?:\s*\|\s*)',
104 'colon' : r'(?:\s*:\s*)',
105
106 'string_single':r'\'(?:[^\'\\]*(?:\\.[^\'\\]*)*)\'',
107 'string_double':r'\"(?:[^\"\\]*(?:\\.[^\"\\]*)*)\"',
108 'string' : r'%(string_double)s|%(string_single)s',
109 'float' : r'\d+\.\d*|\.\d+',
110 'int' : r'\d+',
111
112 'simple_literal' : r'(?:%(string)s|%(float)s|%(int)s)',
113
114 'simple_literal_n' : r'(?:(?P<string>%(string)s)|(?P<float>%(float)s)|(?P<int>%(int)s))',
115
116
117 'array_items': chain_s('expr', 'comma'),
118 'array_items_iter':chain_iter('expr', 'comma'),
119 'larray_items': chain_s('literal', 'comma'),
120 'larray_items_iter':chain_iter('literal', 'comma'),
121 'array' : r'\[\s*%(array_items)s\s*\]',
122 'array_n' : r'\[\s*(?P<array_items>%(array_items)s)\s*\]',
123
124
125 'dictpair' : r'(?:%(expr)s)%(colon)s(?:%(expr)s)',
126 'dictpair_n': r'(?P<key>%(expr)s)%(colon)s(?P<value>%(expr)s)',
127 'dictpairs' : chain_s('dictpair', 'comma'),
128 'dict_pairs_iter':chain_iter('dictpair', 'comma'),
129 'dict' : r'\{\s*%(dictpairs)s\s*\}',
130 'dict_n' : r'\{\s*(?P<dict_items>%(dictpairs)s)\s*\}',
131
132
133 'range' : r':|%(expr)s:|:%(expr)s|%(expr)s:%(expr)s|%(expr)s:%(expr)s:%(expr)s',
134 'range_n' : r'(?P<range_open_both>:)|(?P<range_open_end>%(expr)s):|(?P<range_open_start>:%(expr)s)|(?P<range_full>%(expr)s:%(expr)s)|(?P<range_full_step>%(expr)s:%(expr)s:%(expr)s)',
135
136 'complex_literal': r'(?:%(array)s|%(range)s)',
137 'complex_literal_n': r'(?:(?P<array>%(array_n)s)|(?P<range>%(range_n)s))',
138
139
140
141 'literal': r'(?:%(simple_literal)s|%(complex_literal)s)',
142 'literal_n': r'(?:%(simple_literal_n)s|%(complex_literal_n)s)',
143
144
145 'hash_call' : r'\[\s*%(array_items)s\s*\]',
146 'hash_call_n' : r'\[\s*(?P<hash_params>%(array_items)s)\s*\]',
147
148
149 'func_call' : r'\(\s*%(array_items)s\s*\)',
150 'func_call_n' : r'\(\s*(?P<func_params>%(array_items)s)\s*\)',
151
152 'attribute' : r'\.%(identifier)s',
153 'attribute_n' : r'\.(?P<attribute>%(identifier)s)',
154
155 'identifier' : r'[a-zA-Z_][a-zA-Z0-9_]*',
156
157 'chain_base' : r'(?:%(identifier)s)',
158 'chain_base_n': r'(?:(?P<identifier>%(identifier)s))',
159 'chain_link' : r'(?:%(hash_call)s|%(attribute)s)',
160 'chain_link_n': r'(?:%(hash_call_n)s|%(attribute_n)s)',
161 'chain_links' : chain_s('chain_link'),
162 'chain_links_iter':chain_iter('chain_link'),
163 'method_chain' : r'%(chain_base)s(?:%(chain_links)s)',
164 'method_chain_n': r'(?P<base>%(chain_base_n)s)(?P<items>(?:%(chain_links)s))',
165
166 'expr' : r'(?:%(method_chain)s|%(literal)s)',
167 'expr_n': r'(?:(?P<method_chain>%(method_chain_n)s)|(?P<literal>%(literal_n)s))',
168
169 'whole' : r'^%(expr_n)s$',
170 }
171
173 return reduce(lambda p,d: p%d, [patterns for i in xrange(depth)], regex)
174
177
178
181
184
185
186
187 """
188 Returns [args, kwargs] without resolving or modifying text
189 - args is the list of arguments and keys in their original order
190 - kwargs is a dict
191
192 """
193
194
195 array_items_iter = compile('array_items_iter', BASE_PATTERNS)
196 dict_pairs_iter = compile('dict_pairs_iter', BASE_PATTERNS)
197 chain_links_iter = compile('chain_links_iter', BASE_PATTERNS)
198 whole_re = compile('whole', BASE_PATTERNS)
199 expr_re = compile('expr_n', BASE_PATTERNS)
201 tree = []
202 m = whole_re.match(s)
203 print m.groups()
204 if not m:
205 raise StructureSyntaxError("Invalid syntax: %s" % (s,))
206 d = m.groupdict()
207 if d['literal']:
208 if d['string']: return d['string'][1:-1]
209 elif d['int']: return int(d['int'])
210 elif d['float']: return float(d['float'])
211 elif d['array']:
212 ret = []
213 for m in array_items_iter.finditer(d['array_items']):
214 ret.append(parse_expr(m.group('next')))
215 return ret
216
217
218
219
220
221 elif d['range']:
222
223 return d['range']
224
225 else:
226 raise RuntimeError("")
227 elif d['method_chain']:
228 if d['identifier']:
229 base = d['identifier']
230 else:
231 raise RuntimeError("")
232 ret = [base]
233 for m in chain_links_iter.finditer(d['items']):
234 d = m.groupdict()
235
236
237
238
239
240 if d['hash_params'] != None:
241 args = []
242 for m in array_items_iter.finditer(d['hash_params']):
243 args.append(parse_expr(m.group('next')))
244 ret.append('__getitem__')
245 ret.append(args)
246 elif d['attribute'] != None:
247 ret.append(d['attribute'])
248 else:
249 raise RuntimeError("")
250 return ret
251 else:
252 raise RuntimeError("")
253