self.filename = filename
self.closed = False
self.extensions = {}
- for extension in environment.extensions.itervalues():
+ for extension in environment.iter_extensions():
for tag in extension.tags:
self.extensions[tag] = extension.parse
self._last_identifier = 0
target = self.parse_tuple(simplified=True,
extra_end_rules=extra_end_rules)
else:
- target = self.parse_primary(with_postfix=False)
+ target = self.parse_primary()
target.set_ctx('store')
if not target.can_assign():
self.fail('can\'t assign to %r' % target.__class__.
lineno = self.stream.current.lineno
return left
- def parse_unary(self):
+ def parse_unary(self, with_filter=True):
token_type = self.stream.current.type
lineno = self.stream.current.lineno
if token_type == 'sub':
next(self.stream)
- node = self.parse_unary()
- return nodes.Neg(node, lineno=lineno)
- if token_type == 'add':
+ node = nodes.Neg(self.parse_unary(False), lineno=lineno)
+ elif token_type == 'add':
next(self.stream)
- node = self.parse_unary()
- return nodes.Pos(node, lineno=lineno)
- return self.parse_primary()
+ node = nodes.Pos(self.parse_unary(False), lineno=lineno)
+ else:
+ node = self.parse_primary()
+ node = self.parse_postfix(node)
+ if with_filter:
+ node = self.parse_filter_expr(node)
+ return node
- def parse_primary(self, with_postfix=True):
+ def parse_primary(self):
token = self.stream.current
if token.type == 'name':
if token.value in ('true', 'false', 'True', 'False'):
node = self.parse_dict()
else:
self.fail("unexpected '%s'" % describe_token(token), token.lineno)
- if with_postfix:
- node = self.parse_postfix(node)
return node
def parse_tuple(self, simplified=False, with_condexpr=True,
"""
lineno = self.stream.current.lineno
if simplified:
- parse = lambda: self.parse_primary(with_postfix=False)
+ parse = self.parse_primary
elif with_condexpr:
parse = self.parse_expression
else:
token_type = self.stream.current.type
if token_type == 'dot' or token_type == 'lbracket':
node = self.parse_subscript(node)
+ # calls are valid both after postfix expressions (getattr
+ # and getitem) as well as filters and tests
elif token_type == 'lparen':
node = self.parse_call(node)
- elif token_type == 'pipe':
+ else:
+ break
+ return node
+
+ def parse_filter_expr(self, node):
+ while 1:
+ token_type = self.stream.current.type
+ if token_type == 'pipe':
node = self.parse_filter(node)
elif token_type == 'name' and self.stream.current.value == 'is':
node = self.parse_test(node)
+ # calls are valid both after postfix expressions (getattr
+ # and getitem) as well as filters and tests
+ elif token_type == 'lparen':
+ node = self.parse_call(node)
else:
break
return node