/* vi:set ts=2: */
/* tab size is 2 */

#include <stdio.h>
#include <math.h>

typedef double type;  

char c;

int argc, arg;
char **argv, *p;

void next()
{
	do
		{
			if(arg != argc && !*p) p = argv[++arg];
	
			if(arg != argc)	c = *p++; else c = 0;
		}
	while(c == ' ');
}

void syntax()
{
	int tc, c = -1, g = 1;
	char *t = argv[g];
	
	while(1)
		{
			if(t == p) tc = c;
			c++;
			
			if(g != argc && !*t) t = argv[++g];
	
			if(g != argc) putchar(*t++); else break;
		}
		
	putchar('\n');
	
	if(tc>16)
		{
			for(c=0;c<tc-16;c++) putchar(' ');
			printf("syntax error ---^\n");
		}
	else
		{
			for(c=0;c<tc;c++) putchar(' ');
			printf("^--- syntax error\n");
		}
		
	exit(1);
}

void unknown(char *s)
{
	printf("'%s': unknown function\n",s);
	exit(1);	
}


type E();
type term();

type constant()
{
	type r = 0;
	
	while(c >= '0' && c <= '9') 
		{ r = 10*r + (c-'0'); next(); }
	
	if(c == '.')
		{
			type p = 0.1;
			next();
			
			while(c >= '0' && c <= '9') 
				{ r += p * (c-'0'); p /= 10; next(); }
		}
	
	if(c == 'e' || c == 'E')
		{ 
			type m = 1;			

			next();
		  if(c == '-') { m = -m; next(); } else if(c == '+') next();

			r *= pow(10,m*term());
		}
		
	return r;
}


type function()
{
	char f[20], *p;
	type v;
	
	p = f;
	while(p-f < 19 && c >= 'a' && c <= 'z') { *p++ = c; next(); }
	
	*p = 0;
	
	if(!strcmp(f,"pi")) return M_PI;
	if(!strcmp(f,"e" )) return M_E;

	v = term();
	
	#define mathfunc(a,b) if(!strcmp(f,a)) return b;

	mathfunc("abs"   , fabs(v));
	mathfunc("fabs"  , fabs(v));
	mathfunc("floor" , floor(v));
	mathfunc("ceil"  , ceil(v));
	mathfunc("sqrt"  , sqrt(v));
	mathfunc("exp"   , exp(v));

	mathfunc("sin"   , sin(v));
	mathfunc("cos"   , cos(v));
	mathfunc("tan"   , tan(v));
	mathfunc("asin"  , asin(v));
	mathfunc("acos"  , acos(v));
	mathfunc("atan"  , atan(v));

	mathfunc("sinh"  , sinh(v));
	mathfunc("cosh"  , cosh(v));
	mathfunc("tanh"  , tanh(v));
	mathfunc("asinh" , asinh(v));
	mathfunc("acosh" , acosh(v));
	mathfunc("atanh" , atanh(v));

	mathfunc("ln"    , log(v));
	mathfunc("log"   , log(v)/log(2));
	
	unknown(f);
	return 0;
}

type term()
{
	/*type m = 1;*/
	const int m = 1;
		
	/*
	  if(c == '-') { m = -m; next(); }
	  else 
	  if(c == '+') next();
	*/
		
	if(c=='(' || c=='[')
		{
			type r;
			
			next();
			r = E();
			if(c != ')' && c !=']') syntax();
			
			next();
			return m * r;
		}
	
	else if((c >= '0' && c <= '9') || c == '.')
					return m * constant();
					
	else if(c >= 'a' && c <= 'z')
					return m * function();
}


static inline
type factorial(type v)
{
	type i, r = 1;
	
	for(i=2;i<=v;i++) r *= i;
	return r;
}

type H()
{
	type r = term();
	
	if(c == '!') { next(); r = factorial(r); }
	return r;
}

type G()
{
	type q, r = H();
	
	while(c == '^')
		{ next(); q = G(); r = pow(r,q); }
	
	return r;
}

type F()
{
	type r = G();

	while(1)
		{
			if(c=='*') { next(); r *= G(); }
			else
			if(c=='/') { next(); r /= G(); }
			else
			if(c=='%') { next(); r = fmod(r,G()); }
			else break;
		}
	
	return r;
}

type E()
{
	type r = F();

	while(1)
		{
			if(c=='+') { next(); r += F(); }
			else
			if(c=='-') { next(); r -= F(); }
			else break;
		}
	
	return r;
}

type S()
{
	type r = E();
	
	if(c != 0) syntax();
	return r;
}

void
format(type X)
{
	type i,f;
	int d;
	
	if(!finite(X)) { printf("%f", X); return ; }
	
	f = fabs(modf(X,&i));
	d = floor(log10(fabs(X)))+1;

	/* f is fractional part, i is integer part */ 
		
	/* printf("%.30f\n",(X)); */
	
	if(finite(f) && f!=0)
		{
			char *p, s[2000], t[2000];
			
			sprintf(t, "%%.%df", 15-d);
			sprintf(s,t,f);
			
			/*
			printf("(t=%s)",t);
			printf("(s=%s)",s);
			*/


			/* remove all zeros from s */
			p = s; 
			while(*p) p++; p--;
			while(p>s && *p=='0') *p-- = 0; 
			
			if(s[0] == '1') /* decimal part has been rounded */
				printf("%.0f",i+(X>=0?1:-1));
			else
				{			
					printf("%.0f",i);
					if(s[2] != 0) printf("%s",s+1);
				}
		}
	else
		printf("%.0f",i);

}

int main(int _argc, char **_argv)
{
	argc = _argc;
	argv = _argv;
	arg = 1;
	p = argv[arg];
	
	next();
	format(S());	
	printf("\n");
	
	return 0;
}


syntax highlighted by Code2HTML, v. 0.9.1