191 return util.unescapestr(s) |
192 return util.unescapestr(s) |
192 except ValueError as e: |
193 except ValueError as e: |
193 # mangle Python's exception into our format |
194 # mangle Python's exception into our format |
194 raise error.ParseError(str(e).lower()) |
195 raise error.ParseError(str(e).lower()) |
195 |
196 |
|
197 def _brepr(obj): |
|
198 if isinstance(obj, bytes): |
|
199 return b"'%s'" % util.escapestr(obj) |
|
200 return encoding.strtolocal(repr(obj)) |
|
201 |
196 def _prettyformat(tree, leafnodes, level, lines): |
202 def _prettyformat(tree, leafnodes, level, lines): |
197 if not isinstance(tree, tuple) or tree[0] in leafnodes: |
203 if not isinstance(tree, tuple): |
198 lines.append((level, str(tree))) |
204 lines.append((level, _brepr(tree))) |
|
205 elif tree[0] in leafnodes: |
|
206 rs = map(_brepr, tree[1:]) |
|
207 lines.append((level, '(%s %s)' % (tree[0], ' '.join(rs)))) |
199 else: |
208 else: |
200 lines.append((level, '(%s' % tree[0])) |
209 lines.append((level, '(%s' % tree[0])) |
201 for s in tree[1:]: |
210 for s in tree[1:]: |
202 _prettyformat(s, leafnodes, level + 1, lines) |
211 _prettyformat(s, leafnodes, level + 1, lines) |
203 lines[-1:] = [(lines[-1][0], lines[-1][1] + ')')] |
212 lines[-1:] = [(lines[-1][0], lines[-1][1] + ')')] |
244 ... ('symbol', '5'), |
253 ... ('symbol', '5'), |
245 ... ('symbol', '6')), |
254 ... ('symbol', '6')), |
246 ... ('symbol', '7'))))), |
255 ... ('symbol', '7'))))), |
247 ... ('symbol', '8')))) |
256 ... ('symbol', '8')))) |
248 (func |
257 (func |
249 ('symbol', 'p1') |
258 (symbol 'p1') |
250 (or |
259 (or |
251 (func |
260 (func |
252 ('symbol', 'sort') |
261 (symbol 'sort') |
253 (list |
262 (list |
254 (or |
263 (or |
255 ('symbol', '1') |
264 (symbol '1') |
256 ('symbol', '2') |
265 (symbol '2') |
257 ('symbol', '3')) |
266 (symbol '3')) |
258 (negate |
267 (negate |
259 ('symbol', 'rev')))) |
268 (symbol 'rev')))) |
260 (and |
269 (and |
261 ('symbol', '4') |
270 (symbol '4') |
262 (group |
271 (group |
263 (or |
272 (or |
264 ('symbol', '5') |
273 (symbol '5') |
265 ('symbol', '6') |
274 (symbol '6') |
266 ('symbol', '7')))) |
275 (symbol '7')))) |
267 ('symbol', '8'))) |
276 (symbol '8'))) |
268 """ |
277 """ |
269 if not isinstance(tree, tuple): |
278 if not isinstance(tree, tuple): |
270 return tree |
279 return tree |
271 op = tree[0] |
280 op = tree[0] |
272 if op not in targetnodes: |
281 if op not in targetnodes: |
559 >>> def pprint(tree): |
568 >>> def pprint(tree): |
560 ... print prettyformat(tree, ('_aliasarg', 'string', 'symbol')) |
569 ... print prettyformat(tree, ('_aliasarg', 'string', 'symbol')) |
561 >>> args = ['$1', '$2', 'foo'] |
570 >>> args = ['$1', '$2', 'foo'] |
562 >>> pprint(builddefn('$1 or foo', args)) |
571 >>> pprint(builddefn('$1 or foo', args)) |
563 (or |
572 (or |
564 ('_aliasarg', '$1') |
573 (_aliasarg '$1') |
565 ('_aliasarg', 'foo')) |
574 (_aliasarg 'foo')) |
566 >>> try: |
575 >>> try: |
567 ... builddefn('$1 or $bar', args) |
576 ... builddefn('$1 or $bar', args) |
568 ... except error.ParseError as inst: |
577 ... except error.ParseError as inst: |
569 ... print parseerrordetail(inst) |
578 ... print parseerrordetail(inst) |
570 invalid symbol '$bar' |
579 invalid symbol '$bar' |
571 >>> args = ['$1', '$10', 'foo'] |
580 >>> args = ['$1', '$10', 'foo'] |
572 >>> pprint(builddefn('$10 or baz', args)) |
581 >>> pprint(builddefn('$10 or baz', args)) |
573 (or |
582 (or |
574 ('_aliasarg', '$10') |
583 (_aliasarg '$10') |
575 ('symbol', 'baz')) |
584 (symbol 'baz')) |
576 >>> pprint(builddefn('"$1" or "foo"', args)) |
585 >>> pprint(builddefn('"$1" or "foo"', args)) |
577 (or |
586 (or |
578 ('string', '$1') |
587 (string '$1') |
579 ('string', 'foo')) |
588 (string 'foo')) |
580 """ |
589 """ |
581 tree = cls._parse(defn) |
590 tree = cls._parse(defn) |
582 if args: |
591 if args: |
583 args = set(args) |
592 args = set(args) |
584 else: |
593 else: |