Mercurial > public > mercurial-scm > hg-stable
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() |