Mercurial > hg
changeset 11278:7df88cdf47fd
revset: add support for prefix and suffix versions of : and ::
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Wed, 02 Jun 2010 14:07:46 -0500 |
parents | 2698a95f3f1b |
children | 62ccf4cd6e7f |
files | mercurial/parser.py mercurial/revset.py |
diffstat | 2 files changed, 39 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/parser.py Tue Jun 01 11:18:57 2010 -0500 +++ b/mercurial/parser.py Wed Jun 02 14:07:46 2010 -0500 @@ -23,7 +23,10 @@ def _advance(self): 'advance the tokenizer' t = self.current - self.current = self._iter.next() + try: + self.current = self._iter.next() + except StopIteration: + pass return t def _match(self, m): 'make sure the tokenizer matches an end condition' @@ -49,17 +52,23 @@ # gather tokens until we meet a lower binding strength while bind < self._elements[self.current[0]][0]: token, value = self._advance() - # handle infix rules - infix = self._elements[token][2] - if len(infix) == 3 and infix[2] == self.current[0]: - self._match(infix[2]) - expr = (infix[0], expr, (None)) + e = self._elements[token] + # check for suffix - next token isn't a valid prefix + if len(e) == 4 and not self._elements[self.current[0]][1]: + suffix = e[3] + expr = (suffix[0], expr) else: - if not infix[0]: - raise SyntaxError("not an infix") - expr = (infix[0], expr, self._parse(infix[1])) - if len(infix) == 3: + # handle infix rules + infix = self._elements[token][2] + if len(infix) == 3 and infix[2] == self.current[0]: self._match(infix[2]) + expr = (infix[0], expr, (None)) + else: + if not infix[0]: + raise SyntaxError("not an infix") + expr = (infix[0], expr, self._parse(infix[1])) + if len(infix) == 3: + self._match(infix[2]) return expr def parse(self, message): 'generate a parse tree from a message'
--- a/mercurial/revset.py Tue Jun 01 11:18:57 2010 -0500 +++ b/mercurial/revset.py Wed Jun 02 14:07:46 2010 -0500 @@ -12,8 +12,11 @@ elements = { "(": (20, ("group", 1, ")"), ("func", 1, ")")), "-": (19, ("negate", 19), ("minus", 19)), - "..": (17, None, ("dagrange", 17)), - ":": (15, None, ("range", 15)), + "::": (17, ("dagrangepre", 17), ("dagrange", 17), + ("dagrangepost", 17)), + "..": (17, ("dagrangepre", 17), ("dagrange", 17), + ("dagrangepost", 17)), + ":": (15, ("rangepre", 15), ("range", 15), ("rangepost", 15)), "not": (10, ("not", 10)), "!": (10, ("not", 10)), "and": (5, None, ("and", 5)), @@ -36,11 +39,14 @@ c = program[pos] if c.isspace(): # skip inter-token whitespace pass - elif c in "():,-|&+!": # handle simple operators - yield (c, None) + elif c == ':' and program[pos:pos + 2] == '::': # look ahead carefully + yield ('::', None) + pos += 1 # skip ahead elif c == '.' and program[pos:pos + 2] == '..': # look ahead carefully yield ('..', None) pos += 1 # skip ahead + elif c in "():,-|&+!": # handle simple operators + yield (c, None) elif c in '"\'': # handle quoted strings pos += 1 s = pos @@ -126,6 +132,12 @@ return range(m, n + 1) return range(m, n - 1, -1) +def rangepreset(repo, subset, x): + return range(0, getset(repo, subset, x)[-1] + 1) + +def rangepostset(repo, subset, x): + return range(getset(repo, subset, x)[0], len(repo)) + def dagrangeset(repo, subset, x, y): return andset(repo, subset, ('func', ('symbol', 'descendants'), x), @@ -469,7 +481,11 @@ "negate": negate, "minus": minusset, "range": rangeset, + "rangepre": rangepreset, + "rangepost": rangepostset, "dagrange": dagrangeset, + "dagrangepre": ancestors, + "dagrangepost": descendants, "string": stringset, "symbol": symbolset, "and": andset,