[C con Clase] interprete de expresiones matematicas

Programante programante en gmail.com
Mar Jul 15 11:20:14 CEST 2008


rodolfo rosso paz escribió:
> Hola a todos nuevamente, de nuevo por aqui molestando:
>  
> queria saber si hay una forma de evaluar una expresion matamatica 
> contenida en una cadena y obtener el resultado :
>  
>  
> Ejemplo.
>  
> int x = 3
> var = "x + 5"
> int resultado = evaluar(var)
>  
> y que resultado contenga 8.     me dicen que en java hay una funcion 
> EVAL() y yo recuerdo que en clipper tambien habia lo que se le llamaba 
> macros y solo era necesario colocar & delante de var, y con eso 
> obtenia el resultado de la formula contenida en la cadena.
>  
> ¿hay forma de hacerlo en c++?
>  
>  
> Gracias de antemano
>  
> Rodolfo

En C++ no hay una función eval(), como es el caso de javascript (en java 
tampoco se puede), ya que C es un lenguaje compilado, tu programa tiene 
instrucciones en código máquina, no el compilador, que es quien sabe 
hacer la suma. Por lo tanto, para que eso te funcione tienes que crear a 
mano la lógica de evaluar.
Si sabes que sólo va a haber sumas, te basta separar por el símbolo + y 
sumar los símbolos. Tampoco es lo mismo si te vale ejecutar las 
operaciones en orden que si te interesa que * y / tengan prioridad, que 
haya paréntesis... En esos casos te convendría generar una pila y 
recorrer en preorden las operaciones inorden que le pasas.


#include <stdio.h>

int x;
enum Operaciones { Suma='+', Resta='-' };
int HazOperacion(int Valor1, int Valor2, enum Operaciones Op) {
            switch (Op) {
                     case Suma:
                             return Valor1 + Valor2;
                     case Resta:
                             return Valor1 - Valor2;
            }
}
int Evaluar(const char* Cadena) {
enum Operaciones Operacion = Suma; //Qué operación estamos haciendo
int Resultado = 0; //El resultado parcial
int Valor = 0; //Operando
int i; //Para iterar por cadena
for (i=0; Cadena[i]; i++) {
 switch (Cadena[i]) {
    case ' ': break;
    case '0'...'9':
            Valor = Valor*10 + (Cadena[i] - '0');
            break;
    case 'x':
            Valor = Valor*10 + x;
            break;
    case '+':
    case '-':
          Resultado = HazOperacion(Resultado, Valor, Operacion);
          Valor = 0;
          Operacion = Cadena[i];
          break;
    default:
          fprintf(stderr, "Caracter desconocido %c\n", Cadena[i]);
    }
  }
   return HazOperacion(Resultado, Valor, Operacion); //Si nos queda 
pendiente alguna operación hacerla
}

int main() {
const char* var = "x + 5";
 x = 3;
 
  printf("%s = %d\n", var, Evaluar(var));
 return 0;
}

Este código suma y resta números, así como la variable x. Para la 
mayoría de las operaciones normales, funciona, pero en otras puede no 
dar lo esperado. Por ejempo tratará  "2x + 5" como 28 en vez de 11. 
También juago con el elemento nulo de la suma y la resta, por lo que 
pasar a multiplicar se complica, pero es un buen código de partida para 
estudiar la máquina de estados y cómo ir parseandolas operaciones.






Más información sobre la lista de distribución Cconclase