--- a/mercurial/parser.py Fri Jun 04 20:57:26 2010 -0500
+++ b/mercurial/parser.py Fri Jun 04 20:57:52 2010 -0500
@@ -15,6 +15,8 @@
# an action is a tree node name, a tree label, and an optional match
# __call__(program) parses program into a labelled tree
+import error
+
class parser(object):
def __init__(self, tokenizer, elements, methods=None):
self._tokenizer = tokenizer
@@ -31,14 +33,15 @@
def _match(self, m):
'make sure the tokenizer matches an end condition'
if self.current[0] != m:
- raise SyntaxError(self.current)
+ raise error.ParseError("unexpected token: %s" % self.current[2],
+ pos)
self._advance()
def _parse(self, bind=0):
- token, value = self._advance()
+ token, value, pos = self._advance()
# handle prefix rules on current token
prefix = self._elements[token][1]
if not prefix:
- raise SyntaxError("not a prefix: %s" % token)
+ raise error.ParseError("not a prefix: %s" % token, pos)
if len(prefix) == 1:
expr = (prefix[0], value)
else:
@@ -51,7 +54,7 @@
self._match(prefix[2])
# gather tokens until we meet a lower binding strength
while bind < self._elements[self.current[0]][0]:
- token, value = self._advance()
+ token, value, pos = self._advance()
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]:
@@ -65,7 +68,7 @@
expr = (infix[0], expr, (None))
else:
if not infix[0]:
- raise SyntaxError("not an infix")
+ raise error.ParseError("not an infix: %s" % token, pos)
expr = (infix[0], expr, self._parse(infix[1]))
if len(infix) == 3:
self._match(infix[2])
--- a/mercurial/revset.py Fri Jun 04 20:57:26 2010 -0500
+++ b/mercurial/revset.py Fri Jun 04 20:57:52 2010 -0500
@@ -6,7 +6,7 @@
# GNU General Public License version 2 or any later version.
import re
-import parser, util, hg
+import parser, util, hg, error
import match as _match
elements = {
@@ -40,13 +40,13 @@
if c.isspace(): # skip inter-token whitespace
pass
elif c == ':' and program[pos:pos + 2] == '::': # look ahead carefully
- yield ('::', None)
+ yield ('::', None, pos)
pos += 1 # skip ahead
elif c == '.' and program[pos:pos + 2] == '..': # look ahead carefully
- yield ('..', None)
+ yield ('..', None, pos)
pos += 1 # skip ahead
elif c in "():,-|&+!": # handle simple operators
- yield (c, None)
+ yield (c, None, pos)
elif c in '"\'': # handle quoted strings
pos += 1
s = pos
@@ -56,11 +56,11 @@
pos += 2
continue
if d == c:
- yield ('string', program[s:pos].decode('string-escape'))
+ yield ('string', program[s:pos].decode('string-escape'), s)
break
pos += 1
else:
- raise "unterminated string"
+ raise error.ParseError("unterminated string", s)
elif c.isalnum() or c in '.': # gather up a symbol/keyword
s = pos
pos += 1
@@ -74,21 +74,21 @@
pos += 1
sym = program[s:pos]
if sym in keywords: # operator keywords
- yield (sym, None)
+ yield (sym, None, s)
else:
- yield ('symbol', sym)
+ yield ('symbol', sym, s)
pos -= 1
else:
- raise "syntax error at %d" % pos
+ raise error.ParseError("syntax error", pos)
pos += 1
- yield ('end', None)
+ yield ('end', None, pos)
# helpers
def getstring(x, err):
if x[0] == 'string' or x[0] == 'symbol':
return x[1]
- raise err
+ raise error.ParseError(err)
def getlist(x):
if not x:
@@ -100,12 +100,12 @@
def getpair(x, err):
l = getlist(x)
if len(l) != 2:
- raise err
+ raise error.ParseError(err)
return l
def getset(repo, subset, x):
if not x:
- raise "missing argument"
+ raise error.ParseError("missing argument")
return methods[x[0]](repo, subset, *x[1:])
# operator methods
@@ -124,7 +124,7 @@
def symbolset(repo, subset, x):
if x in symbols:
- raise "can't use %s here" % x
+ raise error.ParseError("can't use %s here" % x)
return stringset(repo, subset, x)
def rangeset(repo, subset, x, y):
@@ -147,12 +147,12 @@
return [r for r in subset if r not in s]
def listset(repo, subset, a, b):
- raise "can't use a list in this context"
+ raise error.ParseError("can't use a list in this context")
def func(repo, subset, a, b):
if a[0] == 'symbol' and a[1] in symbols:
return symbols[a[1]](repo, subset, b)
- raise "that's not a function: %s" % a[1]
+ raise error.ParseError("not a function: %s" % a[1])
# functions
@@ -190,7 +190,7 @@
try:
lim = int(getstring(l[1], "limit wants a number"))
except ValueError:
- raise "wants a number"
+ raise error.ParseError("limit expects a number")
return getset(repo, subset, l[0])[:lim]
def children(repo, subset, x):
@@ -216,7 +216,7 @@
a = getset(repo, subset, l[0])
b = getset(repo, subset, l[1])
if len(a) > 1 or len(b) > 1:
- raise "arguments to ancestor must be single revisions"
+ raise error.ParseError("ancestor args must be single revisions")
return [repo[a[0]].ancestor(repo[b[0]]).rev()]
def ancestors(repo, subset, x):
@@ -231,7 +231,7 @@
def follow(repo, subset, x):
if x:
- raise "follow takes no args"
+ raise error.ParseError("follow takes no args")
p = repo['.'].rev()
s = set(repo.changelog.ancestors(p)) | set([p])
return [r for r in subset if r in s]
@@ -336,7 +336,7 @@
def merge(repo, subset, x):
if x:
- raise "merge takes no args"
+ raise error.ParseError("merge takes no args")
cl = repo.changelog
return [r for r in subset if cl.parentrevs(r)[1] != -1]
@@ -390,7 +390,7 @@
elif k == '-date':
e.append(-c.date()[0])
else:
- raise "unknown sort key %r" % k
+ raise error.ParseError("unknown sort key %r" % k)
e.append(r)
l.append(e)
l.sort()