32 self._elements = elements |
32 self._elements = elements |
33 self._methods = methods |
33 self._methods = methods |
34 self.current = None |
34 self.current = None |
35 |
35 |
36 def _advance(self): |
36 def _advance(self): |
37 b'advance the tokenizer' |
37 """advance the tokenizer""" |
38 t = self.current |
38 t = self.current |
39 self.current = next(self._iter, None) |
39 self.current = next(self._iter, None) |
40 return t |
40 return t |
41 |
41 |
42 def _hasnewterm(self): |
42 def _hasnewterm(self): |
43 b'True if next token may start new term' |
43 """True if next token may start new term""" |
44 return any(self._elements[self.current[0]][1:3]) |
44 return any(self._elements[self.current[0]][1:3]) |
45 |
45 |
46 def _match(self, m): |
46 def _match(self, m): |
47 b'make sure the tokenizer matches an end condition' |
47 """make sure the tokenizer matches an end condition""" |
48 if self.current[0] != m: |
48 if self.current[0] != m: |
49 raise error.ParseError( |
49 raise error.ParseError( |
50 _(b"unexpected token: %s") % self.current[0], self.current[2] |
50 _(b"unexpected token: %s") % self.current[0], self.current[2] |
51 ) |
51 ) |
52 self._advance() |
52 self._advance() |
53 |
53 |
54 def _parseoperand(self, bind, m=None): |
54 def _parseoperand(self, bind, m=None): |
55 b'gather right-hand-side operand until an end condition or binding met' |
55 """gather right-hand-side operand until an end condition or binding |
|
56 met""" |
56 if m and self.current[0] == m: |
57 if m and self.current[0] == m: |
57 expr = None |
58 expr = None |
58 else: |
59 else: |
59 expr = self._parse(bind) |
60 expr = self._parse(bind) |
60 if m: |
61 if m: |
83 else: |
84 else: |
84 raise error.ParseError(_(b"not an infix: %s") % token, pos) |
85 raise error.ParseError(_(b"not an infix: %s") % token, pos) |
85 return expr |
86 return expr |
86 |
87 |
87 def parse(self, tokeniter): |
88 def parse(self, tokeniter): |
88 b'generate a parse tree from tokens' |
89 """generate a parse tree from tokens""" |
89 self._iter = tokeniter |
90 self._iter = tokeniter |
90 self._advance() |
91 self._advance() |
91 res = self._parse() |
92 res = self._parse() |
92 token, value, pos = self.current |
93 token, value, pos = self.current |
93 return res, pos |
94 return res, pos |
94 |
95 |
95 def eval(self, tree): |
96 def eval(self, tree): |
96 b'recursively evaluate a parse tree using node methods' |
97 """recursively evaluate a parse tree using node methods""" |
97 if not isinstance(tree, tuple): |
98 if not isinstance(tree, tuple): |
98 return tree |
99 return tree |
99 return self._methods[tree[0]](*[self.eval(t) for t in tree[1:]]) |
100 return self._methods[tree[0]](*[self.eval(t) for t in tree[1:]]) |
100 |
101 |
101 def __call__(self, tokeniter): |
102 def __call__(self, tokeniter): |
102 b'parse tokens into a parse tree and evaluate if methods given' |
103 """parse tokens into a parse tree and evaluate if methods given""" |
103 t = self.parse(tokeniter) |
104 t = self.parse(tokeniter) |
104 if self._methods: |
105 if self._methods: |
105 return self.eval(t) |
106 return self.eval(t) |
106 return t |
107 return t |
107 |
108 |