comparison mercurial/parser.py @ 25803:b3004d273874

parser: factor out function that parses right-hand side of prefix/infix ops These two had common pattern. The significant difference was just a result expression: prefix: (op-name, rhs) infix: (op-name, lhs, rhs)
author Yuya Nishihara <yuya@tcha.org>
date Sun, 05 Jul 2015 18:09:15 +0900
parents cc741c76b26a
children f0a77cb6316a
comparison
equal deleted inserted replaced
25802:cc741c76b26a 25803:b3004d273874
33 'make sure the tokenizer matches an end condition' 33 'make sure the tokenizer matches an end condition'
34 if self.current[0] != m: 34 if self.current[0] != m:
35 raise error.ParseError(_("unexpected token: %s") % self.current[0], 35 raise error.ParseError(_("unexpected token: %s") % self.current[0],
36 self.current[2]) 36 self.current[2])
37 self._advance() 37 self._advance()
38 def _parseoperand(self, bind, m=None):
39 'gather right-hand-side operand until an end condition or binding met'
40 if m and self.current[0] == m:
41 expr = None
42 else:
43 expr = self._parse(bind)
44 if m:
45 self._match(m)
46 return expr
38 def _parse(self, bind=0): 47 def _parse(self, bind=0):
39 token, value, pos = self._advance() 48 token, value, pos = self._advance()
40 # handle prefix rules on current token 49 # handle prefix rules on current token
41 prefix = self._elements[token][1] 50 prefix = self._elements[token][1]
42 if not prefix: 51 if not prefix:
43 raise error.ParseError(_("not a prefix: %s") % token, pos) 52 raise error.ParseError(_("not a prefix: %s") % token, pos)
44 if len(prefix) == 1: 53 if len(prefix) == 1:
45 expr = (prefix[0], value) 54 expr = (prefix[0], value)
46 else: 55 else:
47 if len(prefix) > 2 and prefix[2] == self.current[0]: 56 expr = (prefix[0], self._parseoperand(*prefix[1:]))
48 self._match(prefix[2])
49 expr = (prefix[0], None)
50 else:
51 expr = (prefix[0], self._parse(prefix[1]))
52 if len(prefix) > 2:
53 self._match(prefix[2])
54 # gather tokens until we meet a lower binding strength 57 # gather tokens until we meet a lower binding strength
55 while bind < self._elements[self.current[0]][0]: 58 while bind < self._elements[self.current[0]][0]:
56 token, value, pos = self._advance() 59 token, value, pos = self._advance()
57 infix, suffix = self._elements[token][2:] 60 infix, suffix = self._elements[token][2:]
58 # check for suffix - next token isn't a valid prefix 61 # check for suffix - next token isn't a valid prefix
60 expr = (suffix[0], expr) 63 expr = (suffix[0], expr)
61 else: 64 else:
62 # handle infix rules 65 # handle infix rules
63 if not infix: 66 if not infix:
64 raise error.ParseError(_("not an infix: %s") % token, pos) 67 raise error.ParseError(_("not an infix: %s") % token, pos)
65 if len(infix) == 3 and infix[2] == self.current[0]: 68 expr = (infix[0], expr, self._parseoperand(*infix[1:]))
66 self._match(infix[2])
67 expr = (infix[0], expr, (None))
68 else:
69 expr = (infix[0], expr, self._parse(infix[1]))
70 if len(infix) == 3:
71 self._match(infix[2])
72 return expr 69 return expr
73 def parse(self, tokeniter): 70 def parse(self, tokeniter):
74 'generate a parse tree from tokens' 71 'generate a parse tree from tokens'
75 self._iter = tokeniter 72 self._iter = tokeniter
76 self._advance() 73 self._advance()