codice:
/* eval_expr.symbol */

int	Plus(int a,int b)
{
	return (a+b);
}

int	Minus(int a,int b)
{
	return (a-b);
}

int	Divide(int a,int b)
{
	return (a/b);
}

int	Multiply(int a,int b)
{
	return (a*b);
}

int	Modulus(int a,int b)
{
	return (a%b);
}

typedef struct _operand
{
	char symbol;
	int  preced;
	int  (*funct)();
} Operand;


Operand	operand [] =
{
	{'+',1,Plus},
	{'-',1,Minus},
	{'/',2,Divide},
	{'*',2,Multiply},
	{'%',2,Modulus},
	{0,0,0}
};

int	FindLastOp(char *str,int preced)
{
	int	pos,i,numParent,retValue;
	   
	//valore di ritorno
	retValue = -2;

	//stato bilanciamento parentesi
	numParent = 0;

	//partiamo da fine stringa
	pos = strlen(str)-1;

	//per ogni carattere str[pos]
	//fino ad arrivare all'inizio dell'espressione
	while (pos>=0)
	{
		//teniamo conto delle parentesi incontrate
		if (str[pos] == ')')
			numParent ++;
		if (str[pos] == '(')
			numParent --;

		i = 0;
		//per tutti gli operatori definiti e finchè le 
		//parentesi non sono bilanciate
		while (!numParent && operand[i].symbol)
		{
			//se il carattere corrente è un'operatore
			if (operand[i].symbol == str[pos])
			{
				retValue = -1;
				if (operand[i].preced == preced)
					return (pos);
			}
			//prossimo operatore
			i++;
		}
		//carattere successivo (o meglio precedente)
		pos--;
	}
	return (retValue);
}

int	is_nb(char *str)
{
	if ( *str == '(' )
	{
		str[strlen(str)-1] = 0;
		return (eval_expr_sub(str+1,0));
	}
	return (atoi(str));
}

int	eval_expr_sub(char *str,int preced)
{
	int	pos;
	char save;
	int	nb2;
	if ((pos = FindLastOp(str,preced))==-1)
		return (eval_expr_sub(str,preced+1));
	if (pos==-2)
		return (is_nb(str));
	nb2 = eval_expr_sub(str+pos+1,preced+1);
	save = str[pos];
	str[pos] = 0;
	pos = 0;
	while (operand[pos].symbol)
	{
		if (save==operand[pos].symbol)
			return (operand[pos].funct(eval_expr_sub(str,preced),nb2));
		pos ++;
	}   
	printf("PB !!!\n");
	return (0);
}


int	eval_expr(char *str)
{
	return (eval_expr_sub(str, 0));
}

#include "eval_expr.c"
int main(int ac,char **av)
{
   if (ac>1)
   {
      printf("%d\n", eval_expr(av[1]));
   } 
   getchar();
}