/* EVALUACION DE EXPRESIONES
J. Rafael RodrIguez Ochoa
//
// CaracterIsticas:
// Dada una expresiOn, (como: "(sin(30)*2+3*4/(2-1) +7)" ) se
// almacena en una cadena y se evalua con la tEcnica de recursividad
// derecha evaluandose conforme se avanza de izquierda a derecha.
//
// Manera de ejecutarse:
// Al correr el programa pedirA el siguiente dato:
// 1.- "\n=> "
// 2.- Teclee la expresiOn terminando con enter
// 3.- a lo que el programa contestarA con el valor numErico
// equivalente
//
// El programa se probO con la siguiente expresiOn
//
// sin(30) * cos(40 - 10)
//-------------------------------------------------------------------------
*/
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <math.h>
#include <alloc.h>
char *lectura(void); //OK
void evalua(char *, int *); //OK
void entero(char *); //OK
int termino(char *); //OK
void funcion(char *, int *); //OK
void parentesis(char *, int *); //OK
struct vars // Variables definidas.
{
char var;
int val;
struct vars *sig;
struct vars *ant;
};
struct vars *pri_v = NULL; // Apuntador a la primera variable
void main ()
{
char *car;
int ok = 1, res;
while (ok)
{
car = lectura();
if (strlen(car) == 0) return;
//printf("\ncadena= %s",car);
evalua(car, &res);
if(res >= 0) printf("\n%d",res);
}
printf("salio\n");
getch();
}
void evalua(char *cadena, int *res)
{
int ent1,ent2;
char c;
c = cadena[0];
ent1 = termino(cadena);
if (c == '(') parentesis(cadena, &ent1);
*res = ent1;
while ( (c=cadena[0]) == '+' || c == '-' || c == '/' || c == '*')
{
++cadena;
if (cadena[0] == '(') parentesis(cadena, &ent2);
else ent2 = termino(cadena);
if (c == '+') *res = *res + ent2;
if (c == '-') *res = *res - ent2;
if (c == '*') *res = *res * ent2;
if (c == '/') *res = *res / ent2;
}
}
void parentesis(char *cad, int *res)
{
int c = cad[0], ent2;
*res = termino(++cad);
while ( (c = cad[0]) != ')')
{
ent2 = termino(++cad);
if (c == '+') *res = *res + ent2;
if (c == '-') *res = *res - ent2;
if (c == '*') *res = *res * ent2;
if (c == '/') *res = *res / ent2;
}
++cad;
}
void entero(char *cadena, int *res)
{
int c=cadena[0];
*res = c -'0';
cadena++;
while( (c = cadena[0]) >= '0' && c <= '9')
*res = *res*10 + (c - '0');
}
char *lectura(void)
{
char *car;
printf("\n=> ");
gets(car);
return car;
}
void funcion(char *cadena, int *res)
{
int c=cadena[0],ent1;
++cadena; ++cadena; ++cadena;
parentesis(cadena, &ent1);
if (c == 's') *res = sin(ent1);
if (c == 'c') *res = cos(ent1);
}
void lista(char *cad, int *res)
{
struct vars *y,*nuevo;
y = pri_v;
while(y)
{
if(y->var == cad[0])
{
*res = y->val;
++cad;
return;
}
y = y->sig;
}
if (cad[1] == '=')
{
nuevo = (vars *)malloc(sizeof(struct vars));
if (!nuevo) {printf("No hay memoria suficiente..."); return;}
nuevo->var = cad[0];
++cad; ++cad; // elimina 'letra' y '='
*res = nuevo->val = termino(cad);
nuevo->ant = NULL; // se aNIade al principio
nuevo->sig = pri_v; // de la lista.
pri_v->ant = nuevo;
pri_v = nuevo;
}
else *res = 0;
}
int termino(char *cad) // "*" O "/"
{
int res,c=cad[0];
if (c >= '0' && c <= '9') entero(cad, &res); // Es entero.
if (c == 's' || c == 'c') funcion(cad, &res); // Es funciOn.
if ( (c == 'a' || c == 'b') || // Es variable.
(c >= 'd' && c <= 'r') ||
(c >= 't' && c <= 'z')
) lista(cad, &res); // Si existe se toma su valor
// si no, se aNIade a la lista.
return res;
}