comparison mercurial/parser.py @ 11289:4215ce511134

revset: raise ParseError exceptions
author Matt Mackall <mpm@selenic.com>
date Fri, 04 Jun 2010 20:57:52 -0500
parents 7df88cdf47fd
children d4cafcb63f77
comparison
equal deleted inserted replaced
11288:2123aad24d56 11289:4215ce511134
13 # tokenizer is an iterator that returns type, value pairs 13 # tokenizer is an iterator that returns type, value pairs
14 # elements is a mapping of types to binding strength, prefix and infix actions 14 # elements is a mapping of types to binding strength, prefix and infix actions
15 # an action is a tree node name, a tree label, and an optional match 15 # an action is a tree node name, a tree label, and an optional match
16 # __call__(program) parses program into a labelled tree 16 # __call__(program) parses program into a labelled tree
17 17
18 import error
19
18 class parser(object): 20 class parser(object):
19 def __init__(self, tokenizer, elements, methods=None): 21 def __init__(self, tokenizer, elements, methods=None):
20 self._tokenizer = tokenizer 22 self._tokenizer = tokenizer
21 self._elements = elements 23 self._elements = elements
22 self._methods = methods 24 self._methods = methods
29 pass 31 pass
30 return t 32 return t
31 def _match(self, m): 33 def _match(self, m):
32 'make sure the tokenizer matches an end condition' 34 'make sure the tokenizer matches an end condition'
33 if self.current[0] != m: 35 if self.current[0] != m:
34 raise SyntaxError(self.current) 36 raise error.ParseError("unexpected token: %s" % self.current[2],
37 pos)
35 self._advance() 38 self._advance()
36 def _parse(self, bind=0): 39 def _parse(self, bind=0):
37 token, value = self._advance() 40 token, value, pos = self._advance()
38 # handle prefix rules on current token 41 # handle prefix rules on current token
39 prefix = self._elements[token][1] 42 prefix = self._elements[token][1]
40 if not prefix: 43 if not prefix:
41 raise SyntaxError("not a prefix: %s" % token) 44 raise error.ParseError("not a prefix: %s" % token, pos)
42 if len(prefix) == 1: 45 if len(prefix) == 1:
43 expr = (prefix[0], value) 46 expr = (prefix[0], value)
44 else: 47 else:
45 if len(prefix) > 2 and prefix[2] == self.current[0]: 48 if len(prefix) > 2 and prefix[2] == self.current[0]:
46 self._match(prefix[2]) 49 self._match(prefix[2])
49 expr = (prefix[0], self._parse(prefix[1])) 52 expr = (prefix[0], self._parse(prefix[1]))
50 if len(prefix) > 2: 53 if len(prefix) > 2:
51 self._match(prefix[2]) 54 self._match(prefix[2])
52 # gather tokens until we meet a lower binding strength 55 # gather tokens until we meet a lower binding strength
53 while bind < self._elements[self.current[0]][0]: 56 while bind < self._elements[self.current[0]][0]:
54 token, value = self._advance() 57 token, value, pos = self._advance()
55 e = self._elements[token] 58 e = self._elements[token]
56 # check for suffix - next token isn't a valid prefix 59 # check for suffix - next token isn't a valid prefix
57 if len(e) == 4 and not self._elements[self.current[0]][1]: 60 if len(e) == 4 and not self._elements[self.current[0]][1]:
58 suffix = e[3] 61 suffix = e[3]
59 expr = (suffix[0], expr) 62 expr = (suffix[0], expr)
63 if len(infix) == 3 and infix[2] == self.current[0]: 66 if len(infix) == 3 and infix[2] == self.current[0]:
64 self._match(infix[2]) 67 self._match(infix[2])
65 expr = (infix[0], expr, (None)) 68 expr = (infix[0], expr, (None))
66 else: 69 else:
67 if not infix[0]: 70 if not infix[0]:
68 raise SyntaxError("not an infix") 71 raise error.ParseError("not an infix: %s" % token, pos)
69 expr = (infix[0], expr, self._parse(infix[1])) 72 expr = (infix[0], expr, self._parse(infix[1]))
70 if len(infix) == 3: 73 if len(infix) == 3:
71 self._match(infix[2]) 74 self._match(infix[2])
72 return expr 75 return expr
73 def parse(self, message): 76 def parse(self, message):