Mercurial > hg
annotate mercurial/parser.py @ 32969:30d0cb279bac
py3: catch binascii.Error raised from binascii.unhexlify
Before Python 3, binsacii.unhexlify used to raise TypeError, now it raises
binascii.Error.
author | Pulkit Goyal <7895pulkit@gmail.com> |
---|---|
date | Tue, 20 Jun 2017 22:11:46 +0530 |
parents | 0f41f1e3c75c |
children | 90896b61fe26 |
rev | line source |
---|---|
11274 | 1 # parser.py - simple top-down operator precedence parser for mercurial |
2 # | |
3 # Copyright 2010 Matt Mackall <mpm@selenic.com> | |
4 # | |
5 # This software may be used and distributed according to the terms of the | |
6 # GNU General Public License version 2 or any later version. | |
7 | |
11449
05af334bac05
parser: fix URL to effbot
Julian Cowley <julian@lava.net>
parents:
11412
diff
changeset
|
8 # see http://effbot.org/zone/simple-top-down-parsing.htm and |
11274 | 9 # http://eli.thegreenplace.net/2010/01/02/top-down-operator-precedence-parsing/ |
10 # for background | |
11 | |
12 # takes a tokenizer and elements | |
25655
b8b73652c1c9
parser: update documentation about tokenizer and elements
Yuya Nishihara <yuya@tcha.org>
parents:
25654
diff
changeset
|
13 # tokenizer is an iterator that returns (type, value, pos) tuples |
25815
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25804
diff
changeset
|
14 # elements is a mapping of types to binding strength, primary, prefix, infix |
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25804
diff
changeset
|
15 # and suffix actions |
11274 | 16 # an action is a tree node name, a tree label, and an optional match |
17500 | 17 # __call__(program) parses program into a labeled tree |
11274 | 18 |
25963
7448df709b2e
parser: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25818
diff
changeset
|
19 from __future__ import absolute_import |
7448df709b2e
parser: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25818
diff
changeset
|
20 |
7448df709b2e
parser: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25818
diff
changeset
|
21 from .i18n import _ |
31484
afb335353d28
util: wrap s.decode('string_escape') calls for future py3 compatibility
Yuya Nishihara <yuya@tcha.org>
parents:
31353
diff
changeset
|
22 from . import ( |
afb335353d28
util: wrap s.decode('string_escape') calls for future py3 compatibility
Yuya Nishihara <yuya@tcha.org>
parents:
31353
diff
changeset
|
23 error, |
afb335353d28
util: wrap s.decode('string_escape') calls for future py3 compatibility
Yuya Nishihara <yuya@tcha.org>
parents:
31353
diff
changeset
|
24 util, |
afb335353d28
util: wrap s.decode('string_escape') calls for future py3 compatibility
Yuya Nishihara <yuya@tcha.org>
parents:
31353
diff
changeset
|
25 ) |
11289
4215ce511134
revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents:
11278
diff
changeset
|
26 |
11274 | 27 class parser(object): |
25654
af329a84310c
parser: accept iterator of tokens instead of tokenizer function and program
Yuya Nishihara <yuya@tcha.org>
parents:
25306
diff
changeset
|
28 def __init__(self, elements, methods=None): |
11274 | 29 self._elements = elements |
30 self._methods = methods | |
13176
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
11449
diff
changeset
|
31 self.current = None |
11274 | 32 def _advance(self): |
33 'advance the tokenizer' | |
34 t = self.current | |
25171
d647f97f88dd
parsers: use 'next' instead of try/except
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20778
diff
changeset
|
35 self.current = next(self._iter, None) |
11274 | 36 return t |
25804
f0a77cb6316a
parser: extract function that tests if next token may start new term
Yuya Nishihara <yuya@tcha.org>
parents:
25803
diff
changeset
|
37 def _hasnewterm(self): |
f0a77cb6316a
parser: extract function that tests if next token may start new term
Yuya Nishihara <yuya@tcha.org>
parents:
25803
diff
changeset
|
38 'True if next token may start new term' |
25815
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25804
diff
changeset
|
39 return any(self._elements[self.current[0]][1:3]) |
25802
cc741c76b26a
parser: remove unused parameter 'pos' from _match()
Yuya Nishihara <yuya@tcha.org>
parents:
25801
diff
changeset
|
40 def _match(self, m): |
11274 | 41 'make sure the tokenizer matches an end condition' |
42 if self.current[0] != m: | |
14701
4b93bd041772
parsers: fix localization markup of parser errors
Mads Kiilerich <mads@kiilerich.com>
parents:
13665
diff
changeset
|
43 raise error.ParseError(_("unexpected token: %s") % self.current[0], |
11305
d4cafcb63f77
cleanups: undefined variables
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
11289
diff
changeset
|
44 self.current[2]) |
11274 | 45 self._advance() |
25803
b3004d273874
parser: factor out function that parses right-hand side of prefix/infix ops
Yuya Nishihara <yuya@tcha.org>
parents:
25802
diff
changeset
|
46 def _parseoperand(self, bind, m=None): |
b3004d273874
parser: factor out function that parses right-hand side of prefix/infix ops
Yuya Nishihara <yuya@tcha.org>
parents:
25802
diff
changeset
|
47 'gather right-hand-side operand until an end condition or binding met' |
b3004d273874
parser: factor out function that parses right-hand side of prefix/infix ops
Yuya Nishihara <yuya@tcha.org>
parents:
25802
diff
changeset
|
48 if m and self.current[0] == m: |
b3004d273874
parser: factor out function that parses right-hand side of prefix/infix ops
Yuya Nishihara <yuya@tcha.org>
parents:
25802
diff
changeset
|
49 expr = None |
b3004d273874
parser: factor out function that parses right-hand side of prefix/infix ops
Yuya Nishihara <yuya@tcha.org>
parents:
25802
diff
changeset
|
50 else: |
b3004d273874
parser: factor out function that parses right-hand side of prefix/infix ops
Yuya Nishihara <yuya@tcha.org>
parents:
25802
diff
changeset
|
51 expr = self._parse(bind) |
b3004d273874
parser: factor out function that parses right-hand side of prefix/infix ops
Yuya Nishihara <yuya@tcha.org>
parents:
25802
diff
changeset
|
52 if m: |
b3004d273874
parser: factor out function that parses right-hand side of prefix/infix ops
Yuya Nishihara <yuya@tcha.org>
parents:
25802
diff
changeset
|
53 self._match(m) |
b3004d273874
parser: factor out function that parses right-hand side of prefix/infix ops
Yuya Nishihara <yuya@tcha.org>
parents:
25802
diff
changeset
|
54 return expr |
11274 | 55 def _parse(self, bind=0): |
11289
4215ce511134
revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents:
11278
diff
changeset
|
56 token, value, pos = self._advance() |
25816
43a8a87fc175
parser: resolve ambiguity where both prefix and primary actions are defined
Yuya Nishihara <yuya@tcha.org>
parents:
25815
diff
changeset
|
57 # handle prefix rules on current token, take as primary if unambiguous |
25815
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25804
diff
changeset
|
58 primary, prefix = self._elements[token][1:3] |
25816
43a8a87fc175
parser: resolve ambiguity where both prefix and primary actions are defined
Yuya Nishihara <yuya@tcha.org>
parents:
25815
diff
changeset
|
59 if primary and not (prefix and self._hasnewterm()): |
25815
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25804
diff
changeset
|
60 expr = (primary, value) |
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25804
diff
changeset
|
61 elif prefix: |
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25804
diff
changeset
|
62 expr = (prefix[0], self._parseoperand(*prefix[1:])) |
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25804
diff
changeset
|
63 else: |
14701
4b93bd041772
parsers: fix localization markup of parser errors
Mads Kiilerich <mads@kiilerich.com>
parents:
13665
diff
changeset
|
64 raise error.ParseError(_("not a prefix: %s") % token, pos) |
11274 | 65 # gather tokens until we meet a lower binding strength |
66 while bind < self._elements[self.current[0]][0]: | |
11289
4215ce511134
revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents:
11278
diff
changeset
|
67 token, value, pos = self._advance() |
25817
42ac9d1d1572
parser: reorder infix/suffix handling to be similar to prefix/primary flow
Yuya Nishihara <yuya@tcha.org>
parents:
25816
diff
changeset
|
68 # handle infix rules, take as suffix if unambiguous |
25815
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25804
diff
changeset
|
69 infix, suffix = self._elements[token][3:] |
25818
455190fb4e51
parser: take suffix action if no infix action is defined
Yuya Nishihara <yuya@tcha.org>
parents:
25817
diff
changeset
|
70 if suffix and not (infix and self._hasnewterm()): |
29767
e5b794063fd4
parser: remove unused binding parameter from suffix action
Yuya Nishihara <yuya@tcha.org>
parents:
29059
diff
changeset
|
71 expr = (suffix, expr) |
25817
42ac9d1d1572
parser: reorder infix/suffix handling to be similar to prefix/primary flow
Yuya Nishihara <yuya@tcha.org>
parents:
25816
diff
changeset
|
72 elif infix: |
42ac9d1d1572
parser: reorder infix/suffix handling to be similar to prefix/primary flow
Yuya Nishihara <yuya@tcha.org>
parents:
25816
diff
changeset
|
73 expr = (infix[0], expr, self._parseoperand(*infix[1:])) |
11274 | 74 else: |
25817
42ac9d1d1572
parser: reorder infix/suffix handling to be similar to prefix/primary flow
Yuya Nishihara <yuya@tcha.org>
parents:
25816
diff
changeset
|
75 raise error.ParseError(_("not an infix: %s") % token, pos) |
11274 | 76 return expr |
25654
af329a84310c
parser: accept iterator of tokens instead of tokenizer function and program
Yuya Nishihara <yuya@tcha.org>
parents:
25306
diff
changeset
|
77 def parse(self, tokeniter): |
af329a84310c
parser: accept iterator of tokens instead of tokenizer function and program
Yuya Nishihara <yuya@tcha.org>
parents:
25306
diff
changeset
|
78 'generate a parse tree from tokens' |
af329a84310c
parser: accept iterator of tokens instead of tokenizer function and program
Yuya Nishihara <yuya@tcha.org>
parents:
25306
diff
changeset
|
79 self._iter = tokeniter |
13176
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
11449
diff
changeset
|
80 self._advance() |
13665
e798e430c5e5
revset: report a parse error if a revset is not parsed completely (issue2654)
Bernhard Leiner <bleiner@gmail.com>
parents:
13176
diff
changeset
|
81 res = self._parse() |
e798e430c5e5
revset: report a parse error if a revset is not parsed completely (issue2654)
Bernhard Leiner <bleiner@gmail.com>
parents:
13176
diff
changeset
|
82 token, value, pos = self.current |
e798e430c5e5
revset: report a parse error if a revset is not parsed completely (issue2654)
Bernhard Leiner <bleiner@gmail.com>
parents:
13176
diff
changeset
|
83 return res, pos |
11274 | 84 def eval(self, tree): |
85 'recursively evaluate a parse tree using node methods' | |
86 if not isinstance(tree, tuple): | |
87 return tree | |
88 return self._methods[tree[0]](*[self.eval(t) for t in tree[1:]]) | |
25654
af329a84310c
parser: accept iterator of tokens instead of tokenizer function and program
Yuya Nishihara <yuya@tcha.org>
parents:
25306
diff
changeset
|
89 def __call__(self, tokeniter): |
af329a84310c
parser: accept iterator of tokens instead of tokenizer function and program
Yuya Nishihara <yuya@tcha.org>
parents:
25306
diff
changeset
|
90 'parse tokens into a parse tree and evaluate if methods given' |
af329a84310c
parser: accept iterator of tokens instead of tokenizer function and program
Yuya Nishihara <yuya@tcha.org>
parents:
25306
diff
changeset
|
91 t = self.parse(tokeniter) |
11274 | 92 if self._methods: |
93 return self.eval(t) | |
94 return t | |
25253
3f1a9b44b8c2
parser: move prettyformat() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
25171
diff
changeset
|
95 |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
96 def splitargspec(spec): |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
97 """Parse spec of function arguments into (poskeys, varkey, keys, optkey) |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
98 |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
99 >>> splitargspec('') |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
100 ([], None, [], None) |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
101 >>> splitargspec('foo bar') |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
102 ([], None, ['foo', 'bar'], None) |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
103 >>> splitargspec('foo *bar baz **qux') |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
104 (['foo'], 'bar', ['baz'], 'qux') |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
105 >>> splitargspec('*foo') |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
106 ([], 'foo', [], None) |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
107 >>> splitargspec('**foo') |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
108 ([], None, [], 'foo') |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
109 """ |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
110 optkey = None |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
111 pre, sep, post = spec.partition('**') |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
112 if sep: |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
113 posts = post.split() |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
114 if not posts: |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
115 raise error.ProgrammingError('no **optkey name provided') |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
116 if len(posts) > 1: |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
117 raise error.ProgrammingError('excessive **optkey names provided') |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
118 optkey = posts[0] |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
119 |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
120 pre, sep, post = pre.partition('*') |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
121 pres = pre.split() |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
122 posts = post.split() |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
123 if sep: |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
124 if not posts: |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
125 raise error.ProgrammingError('no *varkey name provided') |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
126 return pres, posts[0], posts[1:], optkey |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
127 return [], None, pres, optkey |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
128 |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
129 def buildargsdict(trees, funcname, argspec, keyvaluenode, keynode): |
25705
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
130 """Build dict from list containing positional and keyword arguments |
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
131 |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
132 Arguments are specified by a tuple of ``(poskeys, varkey, keys, optkey)`` |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
133 where |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
134 |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
135 - ``poskeys``: list of names of positional arguments |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
136 - ``varkey``: optional argument name that takes up remainder |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
137 - ``keys``: list of names that can be either positional or keyword arguments |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
138 - ``optkey``: optional argument name that takes up excess keyword arguments |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
139 |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
140 If ``varkey`` specified, all ``keys`` must be given as keyword arguments. |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
141 |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
142 Invalid keywords, too few positional arguments, or too many positional |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
143 arguments are rejected, but missing keyword arguments are just omitted. |
25705
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
144 """ |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
145 poskeys, varkey, keys, optkey = argspec |
30752
ffd324eaf994
parser: make buildargsdict() precompute position where keyword args start
Yuya Nishihara <yuya@tcha.org>
parents:
30332
diff
changeset
|
146 kwstart = next((i for i, x in enumerate(trees) if x[0] == keyvaluenode), |
ffd324eaf994
parser: make buildargsdict() precompute position where keyword args start
Yuya Nishihara <yuya@tcha.org>
parents:
30332
diff
changeset
|
147 len(trees)) |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
148 if kwstart < len(poskeys): |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
149 raise error.ParseError(_("%(func)s takes at least %(nargs)d positional " |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
150 "arguments") |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
151 % {'func': funcname, 'nargs': len(poskeys)}) |
31920
a98540ea1e42
parser: verify excessive number of args excluding kwargs in buildargsdict()
Yuya Nishihara <yuya@tcha.org>
parents:
31484
diff
changeset
|
152 if not varkey and kwstart > len(poskeys) + len(keys): |
a98540ea1e42
parser: verify excessive number of args excluding kwargs in buildargsdict()
Yuya Nishihara <yuya@tcha.org>
parents:
31484
diff
changeset
|
153 raise error.ParseError(_("%(func)s takes at most %(nargs)d positional " |
a98540ea1e42
parser: verify excessive number of args excluding kwargs in buildargsdict()
Yuya Nishihara <yuya@tcha.org>
parents:
31484
diff
changeset
|
154 "arguments") |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
155 % {'func': funcname, |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
156 'nargs': len(poskeys) + len(keys)}) |
31922
0f41f1e3c75c
parser: preserve order of keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
31921
diff
changeset
|
157 args = util.sortdict() |
25705
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
158 # consume positional arguments |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
159 for k, x in zip(poskeys, trees[:kwstart]): |
25705
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
160 args[k] = x |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
161 if varkey: |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
162 args[varkey] = trees[len(args):kwstart] |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
163 else: |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
164 for k, x in zip(keys, trees[len(args):kwstart]): |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
165 args[k] = x |
25705
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
166 # remainder should be keyword arguments |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
167 if optkey: |
31922
0f41f1e3c75c
parser: preserve order of keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
31921
diff
changeset
|
168 args[optkey] = util.sortdict() |
30752
ffd324eaf994
parser: make buildargsdict() precompute position where keyword args start
Yuya Nishihara <yuya@tcha.org>
parents:
30332
diff
changeset
|
169 for x in trees[kwstart:]: |
25705
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
170 if x[0] != keyvaluenode or x[1][0] != keynode: |
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
171 raise error.ParseError(_("%(func)s got an invalid argument") |
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
172 % {'func': funcname}) |
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
173 k = x[1][1] |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
174 if k in keys: |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
175 d = args |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
176 elif not optkey: |
25705
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
177 raise error.ParseError(_("%(func)s got an unexpected keyword " |
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
178 "argument '%(key)s'") |
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
179 % {'func': funcname, 'key': k}) |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
180 else: |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
181 d = args[optkey] |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
182 if k in d: |
25705
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
183 raise error.ParseError(_("%(func)s got multiple values for keyword " |
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
184 "argument '%(key)s'") |
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
185 % {'func': funcname, 'key': k}) |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
186 d[k] = x[2] |
25705
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
187 return args |
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
188 |
26231
87c9c562c37a
parser: move unescape helper from templater
Yuya Nishihara <yuya@tcha.org>
parents:
25963
diff
changeset
|
189 def unescapestr(s): |
87c9c562c37a
parser: move unescape helper from templater
Yuya Nishihara <yuya@tcha.org>
parents:
25963
diff
changeset
|
190 try: |
31484
afb335353d28
util: wrap s.decode('string_escape') calls for future py3 compatibility
Yuya Nishihara <yuya@tcha.org>
parents:
31353
diff
changeset
|
191 return util.unescapestr(s) |
26231
87c9c562c37a
parser: move unescape helper from templater
Yuya Nishihara <yuya@tcha.org>
parents:
25963
diff
changeset
|
192 except ValueError as e: |
87c9c562c37a
parser: move unescape helper from templater
Yuya Nishihara <yuya@tcha.org>
parents:
25963
diff
changeset
|
193 # mangle Python's exception into our format |
87c9c562c37a
parser: move unescape helper from templater
Yuya Nishihara <yuya@tcha.org>
parents:
25963
diff
changeset
|
194 raise error.ParseError(str(e).lower()) |
87c9c562c37a
parser: move unescape helper from templater
Yuya Nishihara <yuya@tcha.org>
parents:
25963
diff
changeset
|
195 |
25254
060bdfef2517
parser: extract closure of prettyformat() to a top-level function
Yuya Nishihara <yuya@tcha.org>
parents:
25253
diff
changeset
|
196 def _prettyformat(tree, leafnodes, level, lines): |
060bdfef2517
parser: extract closure of prettyformat() to a top-level function
Yuya Nishihara <yuya@tcha.org>
parents:
25253
diff
changeset
|
197 if not isinstance(tree, tuple) or tree[0] in leafnodes: |
060bdfef2517
parser: extract closure of prettyformat() to a top-level function
Yuya Nishihara <yuya@tcha.org>
parents:
25253
diff
changeset
|
198 lines.append((level, str(tree))) |
060bdfef2517
parser: extract closure of prettyformat() to a top-level function
Yuya Nishihara <yuya@tcha.org>
parents:
25253
diff
changeset
|
199 else: |
060bdfef2517
parser: extract closure of prettyformat() to a top-level function
Yuya Nishihara <yuya@tcha.org>
parents:
25253
diff
changeset
|
200 lines.append((level, '(%s' % tree[0])) |
060bdfef2517
parser: extract closure of prettyformat() to a top-level function
Yuya Nishihara <yuya@tcha.org>
parents:
25253
diff
changeset
|
201 for s in tree[1:]: |
060bdfef2517
parser: extract closure of prettyformat() to a top-level function
Yuya Nishihara <yuya@tcha.org>
parents:
25253
diff
changeset
|
202 _prettyformat(s, leafnodes, level + 1, lines) |
060bdfef2517
parser: extract closure of prettyformat() to a top-level function
Yuya Nishihara <yuya@tcha.org>
parents:
25253
diff
changeset
|
203 lines[-1:] = [(lines[-1][0], lines[-1][1] + ')')] |
060bdfef2517
parser: extract closure of prettyformat() to a top-level function
Yuya Nishihara <yuya@tcha.org>
parents:
25253
diff
changeset
|
204 |
25253
3f1a9b44b8c2
parser: move prettyformat() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
25171
diff
changeset
|
205 def prettyformat(tree, leafnodes): |
3f1a9b44b8c2
parser: move prettyformat() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
25171
diff
changeset
|
206 lines = [] |
25254
060bdfef2517
parser: extract closure of prettyformat() to a top-level function
Yuya Nishihara <yuya@tcha.org>
parents:
25253
diff
changeset
|
207 _prettyformat(tree, leafnodes, 0, lines) |
25253
3f1a9b44b8c2
parser: move prettyformat() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
25171
diff
changeset
|
208 output = '\n'.join((' ' * l + s) for l, s in lines) |
3f1a9b44b8c2
parser: move prettyformat() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
25171
diff
changeset
|
209 return output |
25306
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
210 |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
211 def simplifyinfixops(tree, targetnodes): |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
212 """Flatten chained infix operations to reduce usage of Python stack |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
213 |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
214 >>> def f(tree): |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
215 ... print prettyformat(simplifyinfixops(tree, ('or',)), ('symbol',)) |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
216 >>> f(('or', |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
217 ... ('or', |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
218 ... ('symbol', '1'), |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
219 ... ('symbol', '2')), |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
220 ... ('symbol', '3'))) |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
221 (or |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
222 ('symbol', '1') |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
223 ('symbol', '2') |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
224 ('symbol', '3')) |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
225 >>> f(('func', |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
226 ... ('symbol', 'p1'), |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
227 ... ('or', |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
228 ... ('or', |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
229 ... ('func', |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
230 ... ('symbol', 'sort'), |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
231 ... ('list', |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
232 ... ('or', |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
233 ... ('or', |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
234 ... ('symbol', '1'), |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
235 ... ('symbol', '2')), |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
236 ... ('symbol', '3')), |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
237 ... ('negate', |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
238 ... ('symbol', 'rev')))), |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
239 ... ('and', |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
240 ... ('symbol', '4'), |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
241 ... ('group', |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
242 ... ('or', |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
243 ... ('or', |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
244 ... ('symbol', '5'), |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
245 ... ('symbol', '6')), |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
246 ... ('symbol', '7'))))), |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
247 ... ('symbol', '8')))) |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
248 (func |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
249 ('symbol', 'p1') |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
250 (or |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
251 (func |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
252 ('symbol', 'sort') |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
253 (list |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
254 (or |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
255 ('symbol', '1') |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
256 ('symbol', '2') |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
257 ('symbol', '3')) |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
258 (negate |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
259 ('symbol', 'rev')))) |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
260 (and |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
261 ('symbol', '4') |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
262 (group |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
263 (or |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
264 ('symbol', '5') |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
265 ('symbol', '6') |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
266 ('symbol', '7')))) |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
267 ('symbol', '8'))) |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
268 """ |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
269 if not isinstance(tree, tuple): |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
270 return tree |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
271 op = tree[0] |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
272 if op not in targetnodes: |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
273 return (op,) + tuple(simplifyinfixops(x, targetnodes) for x in tree[1:]) |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
274 |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
275 # walk down left nodes taking each right node. no recursion to left nodes |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
276 # because infix operators are left-associative, i.e. left tree is deep. |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
277 # e.g. '1 + 2 + 3' -> (+ (+ 1 2) 3) -> (+ 1 2 3) |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
278 simplified = [] |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
279 x = tree |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
280 while x[0] == op: |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
281 l, r = x[1:] |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
282 simplified.append(simplifyinfixops(r, targetnodes)) |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
283 x = l |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
284 simplified.append(simplifyinfixops(x, targetnodes)) |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
285 simplified.append(op) |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
286 return tuple(reversed(simplified)) |
28720
639e0f1e8ffa
parser: move parsererrordetail() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
26231
diff
changeset
|
287 |
639e0f1e8ffa
parser: move parsererrordetail() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
26231
diff
changeset
|
288 def parseerrordetail(inst): |
639e0f1e8ffa
parser: move parsererrordetail() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
26231
diff
changeset
|
289 """Compose error message from specified ParseError object |
639e0f1e8ffa
parser: move parsererrordetail() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
26231
diff
changeset
|
290 """ |
639e0f1e8ffa
parser: move parsererrordetail() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
26231
diff
changeset
|
291 if len(inst.args) > 1: |
31353
089e37802fb3
parser: use %d instead of %s for interpolating error position
Augie Fackler <augie@google.com>
parents:
30753
diff
changeset
|
292 return _('at %d: %s') % (inst.args[1], inst.args[0]) |
28720
639e0f1e8ffa
parser: move parsererrordetail() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
26231
diff
changeset
|
293 else: |
639e0f1e8ffa
parser: move parsererrordetail() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
26231
diff
changeset
|
294 return inst.args[0] |
28870
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
295 |
28892
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
296 class alias(object): |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
297 """Parsed result of alias""" |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
298 |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
299 def __init__(self, name, args, err, replacement): |
28892
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
300 self.name = name |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
301 self.args = args |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
302 self.error = err |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
303 self.replacement = replacement |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
304 # whether own `error` information is already shown or not. |
28898
8d398155bfda
revset: rename findaliases() to expandaliases()
Yuya Nishihara <yuya@tcha.org>
parents:
28897
diff
changeset
|
305 # this avoids showing same warning multiple times at each |
8d398155bfda
revset: rename findaliases() to expandaliases()
Yuya Nishihara <yuya@tcha.org>
parents:
28897
diff
changeset
|
306 # `expandaliases`. |
28892
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
307 self.warned = False |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
308 |
28870
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
309 class basealiasrules(object): |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
310 """Parsing and expansion rule set of aliases |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
311 |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
312 This is a helper for fileset/revset/template aliases. A concrete rule set |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
313 should be made by sub-classing this and implementing class/static methods. |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
314 |
30332
318a24b52eeb
spelling: fixes of non-dictionary words
Mads Kiilerich <madski@unity3d.com>
parents:
29767
diff
changeset
|
315 It supports alias expansion of symbol and function-call styles:: |
28870
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
316 |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
317 # decl = defn |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
318 h = heads(default) |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
319 b($1) = ancestors($1) - ancestors(default) |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
320 """ |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
321 # typically a config section, which will be included in error messages |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
322 _section = None |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
323 # tag of symbol node |
28870
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
324 _symbolnode = 'symbol' |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
325 |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
326 def __new__(cls): |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
327 raise TypeError("'%s' is not instantiatable" % cls.__name__) |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
328 |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
329 @staticmethod |
28875
2e9f5453ab5a
parser: unify parser function of alias declaration and definition
Yuya Nishihara <yuya@tcha.org>
parents:
28873
diff
changeset
|
330 def _parse(spec): |
2e9f5453ab5a
parser: unify parser function of alias declaration and definition
Yuya Nishihara <yuya@tcha.org>
parents:
28873
diff
changeset
|
331 """Parse an alias name, arguments and definition""" |
28870
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
332 raise NotImplementedError |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
333 |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
334 @staticmethod |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
335 def _trygetfunc(tree): |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
336 """Return (name, args) if tree is a function; otherwise None""" |
28870
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
337 raise NotImplementedError |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
338 |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
339 @classmethod |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
340 def _builddecl(cls, decl): |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
341 """Parse an alias declaration into ``(name, args, errorstr)`` |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
342 |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
343 This function analyzes the parsed tree. The parsing rule is provided |
28875
2e9f5453ab5a
parser: unify parser function of alias declaration and definition
Yuya Nishihara <yuya@tcha.org>
parents:
28873
diff
changeset
|
344 by ``_parse()``. |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
345 |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
346 - ``name``: of declared alias (may be ``decl`` itself at error) |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
347 - ``args``: list of argument names (or None for symbol declaration) |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
348 - ``errorstr``: detail about detected error (or None) |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
349 |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
350 >>> sym = lambda x: ('symbol', x) |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
351 >>> symlist = lambda *xs: ('list',) + tuple(sym(x) for x in xs) |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
352 >>> func = lambda n, a: ('func', sym(n), a) |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
353 >>> parsemap = { |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
354 ... 'foo': sym('foo'), |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
355 ... '$foo': sym('$foo'), |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
356 ... 'foo::bar': ('dagrange', sym('foo'), sym('bar')), |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
357 ... 'foo()': func('foo', None), |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
358 ... '$foo()': func('$foo', None), |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
359 ... 'foo($1, $2)': func('foo', symlist('$1', '$2')), |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
360 ... 'foo(bar_bar, baz.baz)': |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
361 ... func('foo', symlist('bar_bar', 'baz.baz')), |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
362 ... 'foo(bar($1, $2))': |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
363 ... func('foo', func('bar', symlist('$1', '$2'))), |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
364 ... 'foo($1, $2, nested($1, $2))': |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
365 ... func('foo', (symlist('$1', '$2') + |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
366 ... (func('nested', symlist('$1', '$2')),))), |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
367 ... 'foo("bar")': func('foo', ('string', 'bar')), |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
368 ... 'foo($1, $2': error.ParseError('unexpected token: end', 10), |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
369 ... 'foo("bar': error.ParseError('unterminated string', 5), |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
370 ... 'foo($1, $2, $1)': func('foo', symlist('$1', '$2', '$1')), |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
371 ... } |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
372 >>> def parse(expr): |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
373 ... x = parsemap[expr] |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
374 ... if isinstance(x, Exception): |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
375 ... raise x |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
376 ... return x |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
377 >>> def trygetfunc(tree): |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
378 ... if not tree or tree[0] != 'func' or tree[1][0] != 'symbol': |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
379 ... return None |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
380 ... if not tree[2]: |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
381 ... return tree[1][1], [] |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
382 ... if tree[2][0] == 'list': |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
383 ... return tree[1][1], list(tree[2][1:]) |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
384 ... return tree[1][1], [tree[2]] |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
385 >>> class aliasrules(basealiasrules): |
28875
2e9f5453ab5a
parser: unify parser function of alias declaration and definition
Yuya Nishihara <yuya@tcha.org>
parents:
28873
diff
changeset
|
386 ... _parse = staticmethod(parse) |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
387 ... _trygetfunc = staticmethod(trygetfunc) |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
388 >>> builddecl = aliasrules._builddecl |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
389 >>> builddecl('foo') |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
390 ('foo', None, None) |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
391 >>> builddecl('$foo') |
29058
dbed4c4f48ae
parser: rephrase "'$' not for alias arguments" message
Yuya Nishihara <yuya@tcha.org>
parents:
28910
diff
changeset
|
392 ('$foo', None, "invalid symbol '$foo'") |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
393 >>> builddecl('foo::bar') |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
394 ('foo::bar', None, 'invalid format') |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
395 >>> builddecl('foo()') |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
396 ('foo', [], None) |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
397 >>> builddecl('$foo()') |
29058
dbed4c4f48ae
parser: rephrase "'$' not for alias arguments" message
Yuya Nishihara <yuya@tcha.org>
parents:
28910
diff
changeset
|
398 ('$foo()', None, "invalid function '$foo'") |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
399 >>> builddecl('foo($1, $2)') |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
400 ('foo', ['$1', '$2'], None) |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
401 >>> builddecl('foo(bar_bar, baz.baz)') |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
402 ('foo', ['bar_bar', 'baz.baz'], None) |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
403 >>> builddecl('foo($1, $2, nested($1, $2))') |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
404 ('foo($1, $2, nested($1, $2))', None, 'invalid argument list') |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
405 >>> builddecl('foo(bar($1, $2))') |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
406 ('foo(bar($1, $2))', None, 'invalid argument list') |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
407 >>> builddecl('foo("bar")') |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
408 ('foo("bar")', None, 'invalid argument list') |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
409 >>> builddecl('foo($1, $2') |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
410 ('foo($1, $2', None, 'at 10: unexpected token: end') |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
411 >>> builddecl('foo("bar') |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
412 ('foo("bar', None, 'at 5: unterminated string') |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
413 >>> builddecl('foo($1, $2, $1)') |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
414 ('foo', None, 'argument names collide with each other') |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
415 """ |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
416 try: |
28875
2e9f5453ab5a
parser: unify parser function of alias declaration and definition
Yuya Nishihara <yuya@tcha.org>
parents:
28873
diff
changeset
|
417 tree = cls._parse(decl) |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
418 except error.ParseError as inst: |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
419 return (decl, None, parseerrordetail(inst)) |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
420 |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
421 if tree[0] == cls._symbolnode: |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
422 # "name = ...." style |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
423 name = tree[1] |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
424 if name.startswith('$'): |
29058
dbed4c4f48ae
parser: rephrase "'$' not for alias arguments" message
Yuya Nishihara <yuya@tcha.org>
parents:
28910
diff
changeset
|
425 return (decl, None, _("invalid symbol '%s'") % name) |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
426 return (name, None, None) |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
427 |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
428 func = cls._trygetfunc(tree) |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
429 if func: |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
430 # "name(arg, ....) = ...." style |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
431 name, args = func |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
432 if name.startswith('$'): |
29058
dbed4c4f48ae
parser: rephrase "'$' not for alias arguments" message
Yuya Nishihara <yuya@tcha.org>
parents:
28910
diff
changeset
|
433 return (decl, None, _("invalid function '%s'") % name) |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
434 if any(t[0] != cls._symbolnode for t in args): |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
435 return (decl, None, _("invalid argument list")) |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
436 if len(args) != len(set(args)): |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
437 return (name, None, _("argument names collide with each other")) |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
438 return (name, [t[1] for t in args], None) |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
439 |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
440 return (decl, None, _("invalid format")) |
28872
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
441 |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
442 @classmethod |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
443 def _relabelargs(cls, tree, args): |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
444 """Mark alias arguments as ``_aliasarg``""" |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
445 if not isinstance(tree, tuple): |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
446 return tree |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
447 op = tree[0] |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
448 if op != cls._symbolnode: |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
449 return (op,) + tuple(cls._relabelargs(x, args) for x in tree[1:]) |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
450 |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
451 assert len(tree) == 2 |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
452 sym = tree[1] |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
453 if sym in args: |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
454 op = '_aliasarg' |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
455 elif sym.startswith('$'): |
29058
dbed4c4f48ae
parser: rephrase "'$' not for alias arguments" message
Yuya Nishihara <yuya@tcha.org>
parents:
28910
diff
changeset
|
456 raise error.ParseError(_("invalid symbol '%s'") % sym) |
28872
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
457 return (op, sym) |
28873
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
458 |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
459 @classmethod |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
460 def _builddefn(cls, defn, args): |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
461 """Parse an alias definition into a tree and marks substitutions |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
462 |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
463 This function marks alias argument references as ``_aliasarg``. The |
28875
2e9f5453ab5a
parser: unify parser function of alias declaration and definition
Yuya Nishihara <yuya@tcha.org>
parents:
28873
diff
changeset
|
464 parsing rule is provided by ``_parse()``. |
28873
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
465 |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
466 ``args`` is a list of alias argument names, or None if the alias |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
467 is declared as a symbol. |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
468 |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
469 >>> parsemap = { |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
470 ... '$1 or foo': ('or', ('symbol', '$1'), ('symbol', 'foo')), |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
471 ... '$1 or $bar': ('or', ('symbol', '$1'), ('symbol', '$bar')), |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
472 ... '$10 or baz': ('or', ('symbol', '$10'), ('symbol', 'baz')), |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
473 ... '"$1" or "foo"': ('or', ('string', '$1'), ('string', 'foo')), |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
474 ... } |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
475 >>> class aliasrules(basealiasrules): |
28875
2e9f5453ab5a
parser: unify parser function of alias declaration and definition
Yuya Nishihara <yuya@tcha.org>
parents:
28873
diff
changeset
|
476 ... _parse = staticmethod(parsemap.__getitem__) |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
477 ... _trygetfunc = staticmethod(lambda x: None) |
28873
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
478 >>> builddefn = aliasrules._builddefn |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
479 >>> def pprint(tree): |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
480 ... print prettyformat(tree, ('_aliasarg', 'string', 'symbol')) |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
481 >>> args = ['$1', '$2', 'foo'] |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
482 >>> pprint(builddefn('$1 or foo', args)) |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
483 (or |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
484 ('_aliasarg', '$1') |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
485 ('_aliasarg', 'foo')) |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
486 >>> try: |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
487 ... builddefn('$1 or $bar', args) |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
488 ... except error.ParseError as inst: |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
489 ... print parseerrordetail(inst) |
29058
dbed4c4f48ae
parser: rephrase "'$' not for alias arguments" message
Yuya Nishihara <yuya@tcha.org>
parents:
28910
diff
changeset
|
490 invalid symbol '$bar' |
28873
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
491 >>> args = ['$1', '$10', 'foo'] |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
492 >>> pprint(builddefn('$10 or baz', args)) |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
493 (or |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
494 ('_aliasarg', '$10') |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
495 ('symbol', 'baz')) |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
496 >>> pprint(builddefn('"$1" or "foo"', args)) |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
497 (or |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
498 ('string', '$1') |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
499 ('string', 'foo')) |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
500 """ |
28875
2e9f5453ab5a
parser: unify parser function of alias declaration and definition
Yuya Nishihara <yuya@tcha.org>
parents:
28873
diff
changeset
|
501 tree = cls._parse(defn) |
28873
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
502 if args: |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
503 args = set(args) |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
504 else: |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
505 args = set() |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
506 return cls._relabelargs(tree, args) |
28892
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
507 |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
508 @classmethod |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
509 def build(cls, decl, defn): |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
510 """Parse an alias declaration and definition into an alias object""" |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
511 repl = efmt = None |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
512 name, args, err = cls._builddecl(decl) |
28892
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
513 if err: |
29059
8eba4cdcfd81
parser: shorten prefix of alias parsing errors
Yuya Nishihara <yuya@tcha.org>
parents:
29058
diff
changeset
|
514 efmt = _('bad declaration of %(section)s "%(name)s": %(error)s') |
28892
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
515 else: |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
516 try: |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
517 repl = cls._builddefn(defn, args) |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
518 except error.ParseError as inst: |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
519 err = parseerrordetail(inst) |
29059
8eba4cdcfd81
parser: shorten prefix of alias parsing errors
Yuya Nishihara <yuya@tcha.org>
parents:
29058
diff
changeset
|
520 efmt = _('bad definition of %(section)s "%(name)s": %(error)s') |
28892
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
521 if err: |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
522 err = efmt % {'section': cls._section, 'name': name, 'error': err} |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
523 return alias(name, args, err, repl) |
28893
ee11167fe1da
parser: extract helper that creates a dict of aliases
Yuya Nishihara <yuya@tcha.org>
parents:
28892
diff
changeset
|
524 |
ee11167fe1da
parser: extract helper that creates a dict of aliases
Yuya Nishihara <yuya@tcha.org>
parents:
28892
diff
changeset
|
525 @classmethod |
ee11167fe1da
parser: extract helper that creates a dict of aliases
Yuya Nishihara <yuya@tcha.org>
parents:
28892
diff
changeset
|
526 def buildmap(cls, items): |
ee11167fe1da
parser: extract helper that creates a dict of aliases
Yuya Nishihara <yuya@tcha.org>
parents:
28892
diff
changeset
|
527 """Parse a list of alias (name, replacement) pairs into a dict of |
ee11167fe1da
parser: extract helper that creates a dict of aliases
Yuya Nishihara <yuya@tcha.org>
parents:
28892
diff
changeset
|
528 alias objects""" |
ee11167fe1da
parser: extract helper that creates a dict of aliases
Yuya Nishihara <yuya@tcha.org>
parents:
28892
diff
changeset
|
529 aliases = {} |
ee11167fe1da
parser: extract helper that creates a dict of aliases
Yuya Nishihara <yuya@tcha.org>
parents:
28892
diff
changeset
|
530 for decl, defn in items: |
ee11167fe1da
parser: extract helper that creates a dict of aliases
Yuya Nishihara <yuya@tcha.org>
parents:
28892
diff
changeset
|
531 a = cls.build(decl, defn) |
ee11167fe1da
parser: extract helper that creates a dict of aliases
Yuya Nishihara <yuya@tcha.org>
parents:
28892
diff
changeset
|
532 aliases[a.name] = a |
ee11167fe1da
parser: extract helper that creates a dict of aliases
Yuya Nishihara <yuya@tcha.org>
parents:
28892
diff
changeset
|
533 return aliases |
28895
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
534 |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
535 @classmethod |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
536 def _getalias(cls, aliases, tree): |
28909
edbffdc7f6a0
parser: make _getalias() return (alias, pattern-args) pair
Yuya Nishihara <yuya@tcha.org>
parents:
28908
diff
changeset
|
537 """If tree looks like an unexpanded alias, return (alias, pattern-args) |
edbffdc7f6a0
parser: make _getalias() return (alias, pattern-args) pair
Yuya Nishihara <yuya@tcha.org>
parents:
28908
diff
changeset
|
538 pair. Return None otherwise. |
28895
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
539 """ |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
540 if not isinstance(tree, tuple): |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
541 return None |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
542 if tree[0] == cls._symbolnode: |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
543 name = tree[1] |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
544 a = aliases.get(name) |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
545 if a and a.args is None: |
28909
edbffdc7f6a0
parser: make _getalias() return (alias, pattern-args) pair
Yuya Nishihara <yuya@tcha.org>
parents:
28908
diff
changeset
|
546 return a, None |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
547 func = cls._trygetfunc(tree) |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
548 if func: |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
549 name, args = func |
28895
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
550 a = aliases.get(name) |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
551 if a and a.args is not None: |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
552 return a, args |
28895
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
553 return None |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
554 |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
555 @classmethod |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
556 def _expandargs(cls, tree, args): |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
557 """Replace _aliasarg instances with the substitution value of the |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
558 same name in args, recursively. |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
559 """ |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
560 if not isinstance(tree, tuple): |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
561 return tree |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
562 if tree[0] == '_aliasarg': |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
563 sym = tree[1] |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
564 return args[sym] |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
565 return tuple(cls._expandargs(t, args) for t in tree) |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
566 |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
567 @classmethod |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
568 def _expand(cls, aliases, tree, expanding, cache): |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
569 if not isinstance(tree, tuple): |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
570 return tree |
28909
edbffdc7f6a0
parser: make _getalias() return (alias, pattern-args) pair
Yuya Nishihara <yuya@tcha.org>
parents:
28908
diff
changeset
|
571 r = cls._getalias(aliases, tree) |
edbffdc7f6a0
parser: make _getalias() return (alias, pattern-args) pair
Yuya Nishihara <yuya@tcha.org>
parents:
28908
diff
changeset
|
572 if r is None: |
28896
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
573 return tuple(cls._expand(aliases, t, expanding, cache) |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
574 for t in tree) |
28909
edbffdc7f6a0
parser: make _getalias() return (alias, pattern-args) pair
Yuya Nishihara <yuya@tcha.org>
parents:
28908
diff
changeset
|
575 a, l = r |
28896
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
576 if a.error: |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
577 raise error.Abort(a.error) |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
578 if a in expanding: |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
579 raise error.ParseError(_('infinite expansion of %(section)s ' |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
580 '"%(name)s" detected') |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
581 % {'section': cls._section, 'name': a.name}) |
28897
c1f254138f44
parser: add short comment how aliases are expanded in phases
Yuya Nishihara <yuya@tcha.org>
parents:
28896
diff
changeset
|
582 # get cacheable replacement tree by expanding aliases recursively |
28896
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
583 expanding.append(a) |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
584 if a.name not in cache: |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
585 cache[a.name] = cls._expand(aliases, a.replacement, expanding, |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
586 cache) |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
587 result = cache[a.name] |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
588 expanding.pop() |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
589 if a.args is None: |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
590 return result |
28897
c1f254138f44
parser: add short comment how aliases are expanded in phases
Yuya Nishihara <yuya@tcha.org>
parents:
28896
diff
changeset
|
591 # substitute function arguments in replacement tree |
28896
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
592 if len(l) != len(a.args): |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
593 raise error.ParseError(_('invalid number of arguments: %d') |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
594 % len(l)) |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
595 l = [cls._expand(aliases, t, [], cache) for t in l] |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
596 return cls._expandargs(result, dict(zip(a.args, l))) |
28895
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
597 |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
598 @classmethod |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
599 def expand(cls, aliases, tree): |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
600 """Expand aliases in tree, recursively. |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
601 |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
602 'aliases' is a dictionary mapping user defined aliases to alias objects. |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
603 """ |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
604 return cls._expand(aliases, tree, [], {}) |