Parses a tokenized arithmetic expression into a parse tree. It calls
        itself recursively to handle bracketed subexpressions.

        @return: Returns a token string.
        @rtype: lems.parser.expr.ExprNode

        @attention: Does not handle unary minuses at the moment. Needs to be
        fixed.

def parse_token_list_rec(self, min_precedence):
        """
        Parses a tokenized arithmetic expression into a parse tree. It calls
        itself recursively to handle bracketed subexpressions.

        @return: Returns a token string.
        @rtype: lems.parser.expr.ExprNode

        @attention: Does not handle unary minuses at the moment. Needs to be
        fixed.
        """

        exit_loop = False

        ExprParser.depth = ExprParser.depth + 1
        if self.debug: print('>>>>> Depth: %i'% ExprParser.depth)

        precedence = min_precedence

        while self.token_list:
            token = self.token_list[0]
            la = self.token_list[1] if len(self.token_list) > 1 else None

            if self.debug: print('0> %s'% self.token_list)
            if self.debug: print('1> Token: %s, next: %s, op stack: %s, val stack: %s, node stack: %s'% (token, la, self.op_stack, self.val_stack, self.node_stack))

            self.token_list = self.token_list[1:]
            
            close_bracket = False
            
            if token == '(':
                np = ExprParser('')
                np.token_list = self.token_list

                nexp = np.parse2()

                self.node_stack.push(nexp)
                self.val_stack.push('$')

                self.token_list = np.token_list
                if self.debug: print('>>> Tokens left: %s'%self.token_list)
                close_bracket = True
            elif token == ')':
                break
            elif self.is_func(token):
                self.op_stack.push(token)
            elif self.is_op(token):
                stack_top = self.op_stack.top()
                if self.debug: print('OP Token: %s (prior: %i), top: %s (prior: %i)'% (token, self.priority(token), stack_top, self.priority(stack_top)))
                if self.priority(token) < self.priority(stack_top):
                    if self.debug: print('  Priority of %s is less than %s'%(token, stack_top))
                    self.node_stack.push(self.cleanup_stacks())
                    self.val_stack.push('$')
                else:
                    if self.debug: print('  Priority of %s is greater than %s'%(token, stack_top))
                

                self.op_stack.push(token)
            else:
                if self.debug: print('Not a bracket func or op...')
                if la == '(':
                    raise Exception("Error parsing expression: %s\nToken: %s is placed like a function but is not recognised!\nKnown functions: %s"%(self.parse_string, token, known_functions))
                stack_top = self.op_stack.top()
                if stack_top == '$':
                    if self.debug: print("option a")
                    self.node_stack.push(ValueNode(token))
                    self.val_stack.push('$')
                else:
                    if (self.is_op(la) and
                        self.priority(stack_top) < self.priority(la)):
                        if self.debug: print("option b")

                        self.node_stack.push(ValueNode(token))
                        self.val_stack.push('$')
                    else:
                        if self.debug: print("option c, nodes: %s"% self.node_stack)
                        op = self.op_stack.pop()

                        right = ValueNode(token)
                        op_node = self.make_op_node(op,right)

                        self.node_stack.push(op_node)
                        self.val_stack.push('$')
                        
            if close_bracket:
                stack_top = self.op_stack.top()
                if self.debug: print("+ Closing bracket, op stack: %s, node stack: %s la: %s"%(self.op_stack, self.node_stack, la))
                if self.debug: print('>>> Tokens left: %s'%self.token_list)
                
                if stack_top == '$':
                    if self.debug: print("+ option a")
                    '''
                    self.node_stack.push(ValueNode(token))
                    self.val_stack.push('$')'''
                else:
                    la = self.token_list[0] if len(self.token_list) > 1 else None
                    if (self.is_op(la) and self.priority(stack_top) < self.priority(la)):
                        if self.debug: print("+ option b")
                        #self.node_stack.push(ValueNode(token))
                        #self.val_stack.push('$')
                    else:
                        if self.debug: print("+ option c, nodes: %s"% self.node_stack)
                        if self.debug: print('35> op stack: %s, val stack: %s, node stack: %s'% ( self.op_stack, self.val_stack, self.node_stack))
                        right = self.node_stack.pop()
                        op = self.op_stack.pop()
                        op_node = self.make_op_node(stack_top,right)
                        if self.debug: print("Made op node: %s, right: %s"%(op_node, right))

                        self.node_stack.push(op_node)
                        self.val_stack.push('$')
                        if self.debug: print('36> op stack: %s, val stack: %s, node stack: %s'% ( self.op_stack, self.val_stack, self.node_stack))
                        
            

            if self.debug: print('2> Token: %s, next: %s, op stack: %s, val stack: %s, node stack: %s'% (token, la, self.op_stack, self.val_stack, self.node_stack))
            if self.debug: print('')

        if self.debug: print('3> op stack: %s, val stack: %s, node stack: %s'% ( self.op_stack, self.val_stack, self.node_stack))
        ret = self.cleanup_stacks()

        if self.debug: print('4> op stack: %s, val stack: %s, node stack: %s'% ( self.op_stack, self.val_stack, self.node_stack))
        if self.debug: print('<<<<< Depth: %s, returning: %s'% (ExprParser.depth, ret))
        ExprParser.depth = ExprParser.depth - 1
        if self.debug: print('')
        return ret