예제 #1
0
 def parse_mul(self):
     left = self.parse_div()
     while self.stream.current.type == 'mul':
         next(self.stream)
         right = self.parse_div()
         left = nodes.Mul(left, right)
     return left
예제 #2
0
 def parse_floordiv(self):
     left = self.parse_mod()
     while self.stream.current.type == 'floordiv':
         next(self.stream)
         right = self.parse_mod()
         left = nodes.FloorDiv(left, right)
     return left
예제 #3
0
 def parse_mod(self):
     left = self.parse_pow()
     while self.stream.current.type == 'mod':
         next(self.stream)
         right = self.parse_pow()
         left = nodes.Mod(left, right)
     return left
예제 #4
0
 def parse_pow(self):
     left = self.parse_unary()
     while self.stream.current.type == 'pow':
         next(self.stream)
         right = self.parse_unary()
         left = nodes.Pow(left, right)
     return left
예제 #5
0
 def parse_test(self, node):
     token = next(self.stream)
     if self.stream.current.test('name:not'):
         next(self.stream)
         negated = True
     else:
         negated = False
     name = self.stream.expect('name').value
     while self.stream.current.type == 'dot':
         next(self.stream)
         name += '.' + self.stream.expect('name').value
     dyn_args = dyn_kwargs = None
     kwargs = []
     if self.stream.current.type == 'lparen':
         args, kwargs, dyn_args, dyn_kwargs = self.parse_call(None)
     elif self.stream.current.type in ('name', 'string', 'integer',
                                       'float', 'lparen', 'lbracket',
                                       'lbrace') and not \
          self.stream.current.test_any('name:else', 'name:or',
                                       'name:and'):
         if self.stream.current.test('name:is'):
             self.fail('You cannot chain multiple tests with is')
         args = [self.parse_expression()]
     else:
         args = []
     node = nodes.Test(node, name, args, kwargs, dyn_args, dyn_kwargs)
     if negated:
         node = nodes.Not(node)
     return node
예제 #6
0
 def parse_sub(self):
     left = self.parse_concat()
     while self.stream.current.type == 'sub':
         next(self.stream)
         right = self.parse_concat()
         left = nodes.Sub(left, right)
     return left
예제 #7
0
 def parse_add(self):
     left = self.parse_sub()
     while self.stream.current.type == 'add':
         next(self.stream)
         right = self.parse_sub()
         left = nodes.Add(left, right)
     return left
예제 #8
0
    def parse_compare(self):
        expr = self.parse_add()
        ops = []
        while 1:
            token_type = self.stream.current.type
            if token_type == 'assign':
                token_type = 'eq'
                warnings.warn(
                    "Operator '=' is deprecated and will be removed in Django 1.10. "
                    "Use '==' instead.",
                    DjangoDeprecationWarning,
                    stacklevel=2)

            if token_type in _compare_operators:
                next(self.stream)
                ops.append(nodes.Operand(token_type, self.parse_add()))
            elif self.stream.skip_if('name:in'):
                ops.append(nodes.Operand('in', self.parse_add()))
            elif self.stream.current.test('name:not') and \
                 self.stream.look().test('name:in'):
                self.stream.skip(2)
                ops.append(nodes.Operand('notin', self.parse_add()))
            else:
                break
        if not ops:
            return expr
        return nodes.Compare(expr, ops)
예제 #9
0
 def __next__(self):
     token = self.stream.current
     if token.type is TOKEN_EOF:
         self.stream.close()
         raise StopIteration()
     next(self.stream)
     return token
예제 #10
0
 def parse_concat(self):
     args = [self.parse_mul()]
     while self.stream.current.type == 'tilde':
         next(self.stream)
         args.append(self.parse_mul())
     if len(args) == 1:
         return args[0]
     return nodes.Concat(args)
예제 #11
0
 def expect(self, expr):
     """Expect a given token type and return it.  This accepts the same
     argument as :meth:`blended_tags.lexer.Token.test`.
     """
     if not self.current.test(expr):
         expr = describe_token_expr(expr)
         raise UnexpectedTokenError(expr, describe_token(self.current))
     try:
         return self.current
     finally:
         next(self)
예제 #12
0
 def parse_primary(self):
     token = self.stream.current
     if token.type == 'name':
         if token.value in ('true', 'false', 'True', 'False'):
             node = nodes.Const(token.value in ('true', 'True'))
         elif token.value in ('none', 'None'):
             node = nodes.Const(None)
         else:
             node = nodes.Name(token.value)
         next(self.stream)
     elif token.type == 'string':
         next(self.stream)
         node = nodes.Const(token.value)
     elif token.type in ('integer', 'float'):
         next(self.stream)
         node = nodes.Const(token.value)
     elif token.type == 'lparen':
         next(self.stream)
         node = self.parse_tuple(explicit_parentheses=True)
         self.stream.expect('rparen')
     elif token.type == 'lbracket':
         node = self.parse_list()
     elif token.type == 'lbrace':
         node = self.parse_dict()
     else:
         self.fail("unexpected '%s'" % describe_token(token))
     return node
예제 #13
0
 def parse_unary(self, with_filter=True):
     token_type = self.stream.current.type
     if token_type == 'sub':
         next(self.stream)
         node = nodes.Neg(self.parse_unary(False))
     elif token_type == 'add':
         next(self.stream)
         node = nodes.Pos(self.parse_unary(False))
     else:
         node = self.parse_primary()
     node = self.parse_postfix(node)
     if with_filter:
         node = self.parse_filter_expr(node)
     return node
예제 #14
0
    def parse_call(self, node):

        token = self.stream.expect('lparen')
        args = []
        kwargs = []
        dyn_args = dyn_kwargs = None
        require_comma = False

        def ensure(expr):
            if not expr:
                self.fail('invalid syntax for function call expression',
                          token.lineno)

        while self.stream.current.type != 'rparen':
            if require_comma:
                self.stream.expect('comma')
                # support for trailing comma
                if self.stream.current.type == 'rparen':
                    break
            if self.stream.current.type == 'mul':
                ensure(dyn_args is None and dyn_kwargs is None)
                next(self.stream)
                dyn_args = self.parse_expression()
            elif self.stream.current.type == 'pow':
                ensure(dyn_kwargs is None)
                next(self.stream)
                dyn_kwargs = self.parse_expression()
            else:
                ensure(dyn_args is None and dyn_kwargs is None)
                if self.stream.current.type == 'name' and \
                    self.stream.look().type == 'assign':
                    key = self.stream.current.value
                    self.stream.skip(2)
                    value = self.parse_expression()
                    kwargs.append(nodes.Keyword(key, value))
                else:
                    ensure(not kwargs)
                    args.append(self.parse_expression())

            require_comma = True
        self.stream.expect('rparen')

        if node is None:
            return args, kwargs, dyn_args, dyn_kwargs
        return nodes.Call(node, args, kwargs, dyn_args, dyn_kwargs)
예제 #15
0
    def parse_subscribed(self):

        if self.stream.current.type == 'colon':
            next(self.stream)
            args = [None]
        else:
            node = self.parse_expression()
            if self.stream.current.type != 'colon':
                return node
            next(self.stream)
            args = [node]

        if self.stream.current.type == 'colon':
            args.append(None)
        elif self.stream.current.type not in ('rbracket', 'comma'):
            args.append(self.parse_expression())
        else:
            args.append(None)

        if self.stream.current.type == 'colon':
            next(self.stream)
            if self.stream.current.type not in ('rbracket', 'comma'):
                args.append(self.parse_expression())
            else:
                args.append(None)
        else:
            args.append(None)

        return nodes.Slice(*args)
예제 #16
0
 def parse_filter(self, node, start_inline=False):
     while self.stream.current.type == 'pipe' or start_inline:
         if not start_inline:
             next(self.stream)
         token = self.stream.expect('name')
         name = token.value
         while self.stream.current.type == 'dot':
             next(self.stream)
             name += '.' + self.stream.expect('name').value
         if self.stream.current.type == 'lparen':
             args, kwargs, dyn_args, dyn_kwargs = self.parse_call(None)
         elif self.stream.current.type == 'colon':
             next(self.stream)
             # this can't just be parsed as an expression because there would
             # be ambiguity with regards to the application of filters down the chain
             args = [self.parse_unary(with_filter=False)]
             kwargs = []
             dyn_args = dyn_kwargs = None
         else:
             args = []
             kwargs = []
             dyn_args = dyn_kwargs = None
         filter_func = self.django_parser.find_filter(name)
         node = nodes.Filter(node, filter_func, name, args, kwargs,
                             dyn_args, dyn_kwargs)
         start_inline = False
     return node
예제 #17
0
 def parse_subscript(self, node):
     token = next(self.stream)
     if token.type == 'dot':
         attr_token = self.stream.current
         next(self.stream)
         if attr_token.type == 'name':
             return nodes.Getattr(node, attr_token.value)
         elif attr_token.type != 'integer':
             self.fail('expected name or number', attr_token.lineno)
         arg = nodes.Const(attr_token.value)
         return nodes.Getitem(node, arg)
     if token.type == 'lbracket':
         args = []
         while self.stream.current.type != 'rbracket':
             if args:
                 self.stream.expect('comma')
             args.append(self.parse_subscribed())
         self.stream.expect('rbracket')
         if len(args) == 1:
             arg = args[0]
         else:
             arg = nodes.Tuple(args)
         return nodes.Getitem(node, arg)
     self.fail('expected subscript expression', self.lineno)
예제 #18
0
 def skip(self, n=1):
     """Got n tokens ahead."""
     for x in range(n):
         next(self)
예제 #19
0
 def next_if(self, expr):
     """Perform the token test and return the token if it matched.
     Otherwise the return value is `None`.
     """
     if self.current.test(expr):
         return next(self)
예제 #20
0
 def parse_not(self):
     if self.stream.current.test('name:not'):
         next(self.stream)
         return nodes.Not(self.parse_not())
     return self.parse_compare()
예제 #21
0
 def look(self):
     """Look at the next token."""
     old_token = next(self)
     result = self.current
     self.push(old_token)
     return result