Evento Docente Universida del Mar

Analizador y evaluador de expresiones aritmeticas

/* EXPRESS.C Analizador y evaluador de expresiones aritmeticas */

#include
#include
#include
#include
#include

#define DELIMITADOR 1
#define VARIABLE 2
#define NUMERO 3

char *prog;
char token[80];
char tipo_token;

void eval_expr( double *res );
void suma_resta( double *res );
void mult_div( double *res );
void exp( double *res );
void monario( double *res );
void parentesis( double *res );
void atomo( double *res );
void devuelve();
void serror( int error );
void obt_token( void );
int esdelim( char c );

main()
{
clrscr();
double res;
char *p;

/*clrscr();*/
p = ( char* ) malloc (100);
if(!p){
printf("\nFallo de asignacion de memoria\n");
exit(0);
}
do{
/*clrscr();*/
prog = p;
printf("\n\nIntroduzca EXPRESION");
printf("\n\n ==> ");
gets(prog);
if(!*prog) break;
eval_expr(&res);
printf("\nEl resultado es : \n\n %1.2f\n", res);
if(!getch()) getch();
} while(*p);

return 0;
}


void eval_expr( double *res )
{
obt_token();
if(!*token){
serror(2);
return;
}
suma_resta(res);
}

void suma_resta( double *res )
{
register char op;
double temp;

mult_div(res);
while((op = *token) == '+' || op == '-')
{
obt_token();
mult_div(&temp);
switch( op ){
case '-' : *res = *res - temp;
break;
case '+' : *res = *res + temp;
break;
}
}
}

void mult_div( double *res )
{
register char op;
double temp;

exp(res);
while((op = *token) == '*' || op == '/' || op == '%')
{
obt_token();
exp(&temp);
switch( op ){
case '*' : *res = *res * temp;
break;
case '/' : *res = *res / temp;
break;
case '%' : *res = (int) *res % (int) temp;
break;
}
}
}

void exp( double *res )
{
double temp, ex;
register int t;

monario(res);
if(*token == '^'){
obt_token();
exp(&temp);
ex = *res;
if(temp == 0.0){
*res = 1.0;
return;
}
for(t = temp-1; t > 0; --t)
*res = (*res) * (double) ex;
}
}

void monario( double *res )
{
register char op;

op = 0;
if((tipo_token == DELIMITADOR) && *token == '+' ||
*token == '-'){
op = *token;
obt_token();
}
parentesis(res);
if(op == '-') *res = -(*res);
}

void parentesis( double *res )
{
if((*token) == '('){
obt_token();
suma_resta(res);
if((*token) != ')')
serror(1);
obt_token();
}
else
atomo(res);
}

void atomo( double *res )
{
if(tipo_token == NUMERO){
*res = atof(token);
obt_token();
return;
}
serror(0);
}

void devuelve()
{
char *t;

t = token;
for(; *t; t++) prog--;
}

void serror( int error )
{
static char *e[] = {
"Error de sintaxis",
"Parentesis no emparejados",
"No hay expresion"
};
printf("\n%s\n", e[error]);
}

void obt_token( void )
{
register char *temp;

tipo_token = 0;
temp = token;
*temp = '\0';

if(!*prog) return;
while(isspace(*prog)) ++prog;

if(strchr("+-*/^%=()", *prog)){
tipo_token = DELIMITADOR;
*temp++ = *prog++;
}
else if(isalpha(*prog)){
while(!esdelim(*prog)) *temp++ = *prog++;
tipo_token = VARIABLE;
}
else if(isdigit(*prog)){
while(!esdelim(*prog)) *temp++ = *prog++;
tipo_token = NUMERO;
}
*temp = '\0';
}

int esdelim( char c )
{
if(strchr(" +-/*%^=()", c) || c==9 || c=='\r' || c==0)
return 1;
return 0;
}

Tags:

2 comentarios:

Anónimo dijo...

hola nues eh estado checando el codigo que pusiste ... se parece mucho al codigo que biene en un libro llamado manual de referencia c ,bueno pues a lo que voya grax por la ayuda de hacer coodigos que son algo complejos...pero al checarlo y jalarlo no corre marca algunos errores que no se que onda ...

Anónimo dijo...

hola nues eh estado checando el codigo que pusiste ... se parece mucho al codigo que biene en un libro llamado manual de referencia c ,bueno pues a lo que voya grax por la ayuda de hacer coodigos que son algo complejos...pero al checarlo y jalarlo no corre marca algunos errores que no se que onda ...