C99 (565 characters)
Minified
#include<stdio.h>
#include<string.h>
#include<math.h>
float X(char*c){struct{float f;int d,c;}N[99],*C,*E,*P;char*o="+-*/^()",*q,d=1,x
=0;for(C=N;*c;){C->f=C->c=0;if(q=strchr(o,*c)){if(*c<42)d+=*c-41?8:-8;else{if(C
==N|C[-1].c)goto F;C->d=d+(q-o)/2*2;C->c=q-o+1;++C;}++c;}else{int n=0;F:sscanf(c
,"%f%n",&C->f,&n);c+=n;C->d=d;++C;}}for(E=N;E-C;++E)x=E->d>x?E->d:x;for(;x>0;--x
)for(E=P=N;E-C;E->d&&!E->c?P=E:0,++E)if(E->d==x&&E->c){switch((E++)->c){
#define Z(x,n)case n:P->f=P->f x E->f;break;
Z(+,1)Z(-,2)Z(*,3)Z(/,4)case 5:P->f=powf(P->f,E->f);}E->d=0;}return N->f;}
Expanded
#include<stdio.h>
#include<string.h>
#include<math.h>
float X(char*c){
struct{
float f;
int d,c;
}N[99],*C,*E,*P;
char*o="+-*/^()",*q,d=1,x=0;
for(C=N;*c;){
C->f=C->c=0;
if(q=strchr(o,*c)){
if(*c<42) // Parentheses.
d+=*c-41?8:-8;
else{ // +-*/^.
if(C==N|C[-1].c)
goto F;
C->d=d+(q-o)/2*2;
C->c=q-o+1;
++C;
}
++c;
}else{
int n=0;
F:
sscanf(c,"%f%n",&C->f,&n);
c+=n;
C->d=d;
++C;
}
}
for(E=N;E-C;++E)
x=E->d>x?E->d:x;
for(;x>0;--x)
for(E=P=N;E-C;E->d&&!E->c?P=E:0,++E)
if(E->d==x&&E->c){
switch((E++)->c){
#define Z(x,n)case n:P->f=P->f x E->f;break;
Z(+,1)
Z(-,2)
Z(*,3)
Z(/,4)
case 5:
P->f=powf(P->f,E->f);
}
E->d=0;
}
return N->f;
}
int main(){
assert(X("2+2")==4);
assert(X("-1^(-3*4/-6)")==1);
assert(X("-2^(2^(4-1))")==256);
assert(X("2*6/4^2*4/3")==1);
puts("success");
}
Explanation
Developed my own technique. Figure it out yourself. =]