##// END OF EJS Templates
revset: raise ParseError exceptions
Matt Mackall -
r11289:4215ce51 default
parent child Browse files
Show More
@@ -15,6 +15,8 b''
15 15 # an action is a tree node name, a tree label, and an optional match
16 16 # __call__(program) parses program into a labelled tree
17 17
18 import error
19
18 20 class parser(object):
19 21 def __init__(self, tokenizer, elements, methods=None):
20 22 self._tokenizer = tokenizer
@@ -31,14 +33,15 b' class parser(object):'
31 33 def _match(self, m):
32 34 'make sure the tokenizer matches an end condition'
33 35 if self.current[0] != m:
34 raise SyntaxError(self.current)
36 raise error.ParseError("unexpected token: %s" % self.current[2],
37 pos)
35 38 self._advance()
36 39 def _parse(self, bind=0):
37 token, value = self._advance()
40 token, value, pos = self._advance()
38 41 # handle prefix rules on current token
39 42 prefix = self._elements[token][1]
40 43 if not prefix:
41 raise SyntaxError("not a prefix: %s" % token)
44 raise error.ParseError("not a prefix: %s" % token, pos)
42 45 if len(prefix) == 1:
43 46 expr = (prefix[0], value)
44 47 else:
@@ -51,7 +54,7 b' class parser(object):'
51 54 self._match(prefix[2])
52 55 # gather tokens until we meet a lower binding strength
53 56 while bind < self._elements[self.current[0]][0]:
54 token, value = self._advance()
57 token, value, pos = self._advance()
55 58 e = self._elements[token]
56 59 # check for suffix - next token isn't a valid prefix
57 60 if len(e) == 4 and not self._elements[self.current[0]][1]:
@@ -65,7 +68,7 b' class parser(object):'
65 68 expr = (infix[0], expr, (None))
66 69 else:
67 70 if not infix[0]:
68 raise SyntaxError("not an infix")
71 raise error.ParseError("not an infix: %s" % token, pos)
69 72 expr = (infix[0], expr, self._parse(infix[1]))
70 73 if len(infix) == 3:
71 74 self._match(infix[2])
@@ -6,7 +6,7 b''
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 import re
9 import parser, util, hg
9 import parser, util, hg, error
10 10 import match as _match
11 11
12 12 elements = {
@@ -40,13 +40,13 b' def tokenize(program):'
40 40 if c.isspace(): # skip inter-token whitespace
41 41 pass
42 42 elif c == ':' and program[pos:pos + 2] == '::': # look ahead carefully
43 yield ('::', None)
43 yield ('::', None, pos)
44 44 pos += 1 # skip ahead
45 45 elif c == '.' and program[pos:pos + 2] == '..': # look ahead carefully
46 yield ('..', None)
46 yield ('..', None, pos)
47 47 pos += 1 # skip ahead
48 48 elif c in "():,-|&+!": # handle simple operators
49 yield (c, None)
49 yield (c, None, pos)
50 50 elif c in '"\'': # handle quoted strings
51 51 pos += 1
52 52 s = pos
@@ -56,11 +56,11 b' def tokenize(program):'
56 56 pos += 2
57 57 continue
58 58 if d == c:
59 yield ('string', program[s:pos].decode('string-escape'))
59 yield ('string', program[s:pos].decode('string-escape'), s)
60 60 break
61 61 pos += 1
62 62 else:
63 raise "unterminated string"
63 raise error.ParseError("unterminated string", s)
64 64 elif c.isalnum() or c in '.': # gather up a symbol/keyword
65 65 s = pos
66 66 pos += 1
@@ -74,21 +74,21 b' def tokenize(program):'
74 74 pos += 1
75 75 sym = program[s:pos]
76 76 if sym in keywords: # operator keywords
77 yield (sym, None)
77 yield (sym, None, s)
78 78 else:
79 yield ('symbol', sym)
79 yield ('symbol', sym, s)
80 80 pos -= 1
81 81 else:
82 raise "syntax error at %d" % pos
82 raise error.ParseError("syntax error", pos)
83 83 pos += 1
84 yield ('end', None)
84 yield ('end', None, pos)
85 85
86 86 # helpers
87 87
88 88 def getstring(x, err):
89 89 if x[0] == 'string' or x[0] == 'symbol':
90 90 return x[1]
91 raise err
91 raise error.ParseError(err)
92 92
93 93 def getlist(x):
94 94 if not x:
@@ -100,12 +100,12 b' def getlist(x):'
100 100 def getpair(x, err):
101 101 l = getlist(x)
102 102 if len(l) != 2:
103 raise err
103 raise error.ParseError(err)
104 104 return l
105 105
106 106 def getset(repo, subset, x):
107 107 if not x:
108 raise "missing argument"
108 raise error.ParseError("missing argument")
109 109 return methods[x[0]](repo, subset, *x[1:])
110 110
111 111 # operator methods
@@ -124,7 +124,7 b' def stringset(repo, subset, x):'
124 124
125 125 def symbolset(repo, subset, x):
126 126 if x in symbols:
127 raise "can't use %s here" % x
127 raise error.ParseError("can't use %s here" % x)
128 128 return stringset(repo, subset, x)
129 129
130 130 def rangeset(repo, subset, x, y):
@@ -147,12 +147,12 b' def notset(repo, subset, x):'
147 147 return [r for r in subset if r not in s]
148 148
149 149 def listset(repo, subset, a, b):
150 raise "can't use a list in this context"
150 raise error.ParseError("can't use a list in this context")
151 151
152 152 def func(repo, subset, a, b):
153 153 if a[0] == 'symbol' and a[1] in symbols:
154 154 return symbols[a[1]](repo, subset, b)
155 raise "that's not a function: %s" % a[1]
155 raise error.ParseError("not a function: %s" % a[1])
156 156
157 157 # functions
158 158
@@ -190,7 +190,7 b' def limit(repo, subset, x):'
190 190 try:
191 191 lim = int(getstring(l[1], "limit wants a number"))
192 192 except ValueError:
193 raise "wants a number"
193 raise error.ParseError("limit expects a number")
194 194 return getset(repo, subset, l[0])[:lim]
195 195
196 196 def children(repo, subset, x):
@@ -216,7 +216,7 b' def ancestor(repo, subset, x):'
216 216 a = getset(repo, subset, l[0])
217 217 b = getset(repo, subset, l[1])
218 218 if len(a) > 1 or len(b) > 1:
219 raise "arguments to ancestor must be single revisions"
219 raise error.ParseError("ancestor args must be single revisions")
220 220 return [repo[a[0]].ancestor(repo[b[0]]).rev()]
221 221
222 222 def ancestors(repo, subset, x):
@@ -231,7 +231,7 b' def descendants(repo, subset, x):'
231 231
232 232 def follow(repo, subset, x):
233 233 if x:
234 raise "follow takes no args"
234 raise error.ParseError("follow takes no args")
235 235 p = repo['.'].rev()
236 236 s = set(repo.changelog.ancestors(p)) | set([p])
237 237 return [r for r in subset if r in s]
@@ -336,7 +336,7 b' def removes(repo, subset, x):'
336 336
337 337 def merge(repo, subset, x):
338 338 if x:
339 raise "merge takes no args"
339 raise error.ParseError("merge takes no args")
340 340 cl = repo.changelog
341 341 return [r for r in subset if cl.parentrevs(r)[1] != -1]
342 342
@@ -390,7 +390,7 b' def sort(repo, subset, x):'
390 390 elif k == '-date':
391 391 e.append(-c.date()[0])
392 392 else:
393 raise "unknown sort key %r" % k
393 raise error.ParseError("unknown sort key %r" % k)
394 394 e.append(r)
395 395 l.append(e)
396 396 l.sort()
General Comments 0
You need to be logged in to leave comments. Login now