00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <ctype.h>
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <string.h>
00026
00027 #include "toolkits/util/regexp.h"
00028 #include "lista.cc"
00029
00030
00031
00032
00033
00034 #define ES_OPERADOR(cad) \
00035 ( (cad)[0] == '+' || (cad)[0] == '-' || (cad)[0] == '*' || (cad)[0] == '/' || (cad)[0] == '^' )
00036
00037
00038
00039
00040
00041 EXPRESION_REGULAR::EXPRESION_REGULAR()
00042 {
00043 Izq = NULL;
00044 Der = NULL;
00045 nombre_variable = NULL;
00046 tipo = OP_INVALIDO;
00047 valor = 0;
00048 ultimo_t = 0;
00049 }
00050
00051 EXPRESION_REGULAR::~EXPRESION_REGULAR()
00052 {
00053 elim();
00054 }
00055
00056 static double TMP_float;
00057
00058 BOOLEAN
00059 EXPRESION_REGULAR::consultar_variable(const char *nombre_variable,
00060 int &tipo, void **ref)
00063 {
00064 if ( strcmp(nombre_variable, "val") == 0 ) {
00065 TMP_float = evaluar(ultimo_t);
00066 tipo = T_FLOAT;
00067 (*ref) = &TMP_float;
00068 return TRUE;
00069 }
00070 return FALSE;
00071 }
00072
00073 void
00074 EXPRESION_REGULAR::elim(void)
00075 {
00076 if ( Izq ) {
00077 delete Izq;
00078 Izq = NULL;
00079 }
00080 if ( Der ) {
00081 delete Der;
00082 Der = NULL;
00083 }
00084 if ( nombre_variable ) {
00085 delete nombre_variable;
00086 nombre_variable = NULL;
00087 }
00088 tipo = OP_INVALIDO;
00089 valor = 0;
00090 }
00091
00092 int
00093 EXPRESION_REGULAR::clasificar_funcion(char *cad)
00094 {
00095 if ( strcmp(cad, "sin") == 0 ) {
00096 return FN_SIN;
00097 }
00098 else if ( strcmp(cad, "cos") == 0 ) {
00099 return FN_COS;
00100 }
00101 else if ( strcmp(cad, "log") == 0 ) {
00102 return FN_LOG;
00103 }
00104 return OP_INVALIDO;
00105 }
00106
00107 BOOLEAN
00108 EXPRESION_REGULAR::leer(LISTA<char *> *Tokens)
00117 {
00118
00119 while ( strcmp((*Tokens)[0], "(") == 0 &&
00120 strcmp((*Tokens)[Tokens->tam() - 1], ")") == 0 ) {
00121 Tokens->elimElem(Tokens->tam()-1);
00122 Tokens->elimElem(0);
00123 }
00124
00125
00126 if ( Tokens->tam() == 1 ) {
00127 if ( ES_OPERADOR((*Tokens)[0]) ) {
00128 fprintf(stderr, "<EXPRESION_REGULAR> PARSE ERROR: "
00129 "Operador \"%s\" mal parquiao'\n", (*Tokens)[0]);
00130 fflush(stderr);
00131 return FALSE;
00132 }
00133 if ( isdigit((*Tokens)[0][0]) ) {
00134 tipo = RA_CONSTANTE;
00135 valor = atof((*Tokens)[0]);
00136 }
00137 else {
00138 tipo = RA_VARIABLE;
00139 nombre_variable = new char[strlen((*Tokens)[0])];
00140 strcpy(nombre_variable, (*Tokens)[0]);
00141 if ( strcmp(nombre_variable, "PI") == 0 ) {
00142 tipo = RA_CONSTANTE;
00143 valor = PI;
00144 return TRUE;
00145 }
00146 else if ( strcmp(nombre_variable, "t") != 0 ) {
00147 fprintf(stderr,"<EXPRESION_REGULAR> ERROR:"
00148 "Solo se acepta la variable \"t\" en esta version!\n");
00149 fflush(stderr);
00150 return FALSE;
00151 }
00152 }
00153 return TRUE;
00154 }
00155
00156
00157 int i;
00158 int nivel = 0;
00159 LISTA <int> conectivos_principales;
00160 LISTA <char *> izq;
00161 LISTA <char *> der;
00162 int conectivo_principal = -1;
00163
00164
00165 for ( i = 0; i < Tokens->tam(); i++ ) {
00166 if ( (*Tokens)[i][0] == '(' ) nivel++;
00167 else if ( (*Tokens)[i][0] == ')' ) nivel--;
00168 if ( nivel == 0 && ES_OPERADOR((*Tokens)[i]) ) {
00169 conectivos_principales.anx(i);
00170 }
00171 }
00172
00173
00174 if ( conectivos_principales.tam() > 0 ) {
00175 conectivo_principal = conectivos_principales[0];
00176 }
00177 else {
00178 tipo = clasificar_funcion((*Tokens)[0]);
00179 if ( tipo == OP_INVALIDO ) {
00180 fprintf(stderr,"<EXPRESION_REGULAR> ERROR: La "
00181 "funcion \"%s\" no se soporta!\n", (*Tokens)[0]);
00182 fflush(stderr);
00183 return FALSE;
00184 }
00185 Der = new EXPRESION_REGULAR();
00186 for ( i = 1; i < Tokens->tam(); i++ ) {
00187 der.anx((*Tokens)[i]);
00188 }
00189 return Der->leer(&der);
00190 }
00191
00192 for ( i = 0; i < conectivos_principales.tam(); i++ ) {
00193 if ( (*Tokens)[conectivos_principales[i]][0] == '*' ||
00194 (*Tokens)[conectivos_principales[i]][0] == '/' ) {
00195 conectivo_principal = conectivos_principales[i];
00196 break;
00197 }
00198 }
00199
00200 for ( i = 0; i < conectivos_principales.tam(); i++ ) {
00201 if ( (*Tokens)[conectivos_principales[i]][0] == '+' ||
00202 (*Tokens)[conectivos_principales[i]][0] == '-' ) {
00203 conectivo_principal = conectivos_principales[i];
00204 break;
00205 }
00206 }
00207
00208
00209 int op = (*Tokens)[conectivo_principal][0];
00210
00211 if ( op != '-' && conectivo_principal == 0 ) {
00212 fprintf(stderr,
00213 "<EXPRESION_REGULAR> El operador \"%c\" no es unario.\n", op);
00214 fflush(stderr);
00215 return FALSE;
00216 }
00217 else if ( op == '-' && conectivo_principal == 0 ) {
00218 tipo = OP_NEGACION;
00219 Der = new EXPRESION_REGULAR();
00220 for ( i = 1; i < Tokens->tam(); i++ ) {
00221 der.anx((*Tokens)[i]);
00222 }
00223 if ( !Der->leer(&der) ) return FALSE;
00224 else return TRUE;
00225 }
00226 else {
00227 for ( i = 0; i < conectivo_principal && i < Tokens->tam(); i++ ) {
00228 izq.anx((*Tokens)[i]);
00229 }
00230 for ( i = conectivo_principal + 1; i < Tokens->tam(); i++ ) {
00231 der.anx((*Tokens)[i]);
00232 }
00233 }
00234
00235 switch ( op ) {
00236 case '+': tipo = OP_SUMA; break;
00237 case '-': tipo = OP_RESTA; break;
00238 case '*': tipo = OP_MULTIPLICACION; break;
00239 case '/': tipo = OP_DIVISION; break;
00240 case '^': tipo = OP_EXPONENTE; break;
00241 default: break;
00242 }
00243
00244 Izq = new EXPRESION_REGULAR();
00245 Der = new EXPRESION_REGULAR();
00246
00247 if ( !Izq->leer(&izq) || !Der->leer(&der) ) return FALSE;
00248 return TRUE;
00249 }
00250
00251 BOOLEAN
00252 EXPRESION_REGULAR::init(char *fuente)
00260 {
00261 elim();
00262
00263
00264 char *linea = new char[3 * strlen(fuente) + 1];
00265 int i, j;
00266 int nivel = 0;
00267
00268 for ( i = 0, j = 0; i < fuente[i]; i++, j++ ) {
00269 if ( fuente[i] == '(' || fuente[i] == ')' || fuente[i] == '+' ||
00270 fuente[i] == '-' || fuente[i] == '*' || fuente[i] == '/' ||
00271 fuente[i] == '^' ) {
00272 linea[j] = ' '; j++;
00273 linea[j] = fuente[i]; j++;
00274 linea[j] = ' ';
00275 }
00276 else {
00277 linea[j] = fuente[i];
00278 }
00279 if ( fuente[i] == '(' ) nivel++;
00280 else if ( fuente[i] == ')' ) nivel--;
00281 }
00282 linea[j] = '\0';
00283
00284 if ( nivel != 0 ) {
00285 fprintf(stderr,
00286 "<EXPRESION_REGULAR> PARSE ERROR: Parentesis des-balanceados!\n");
00287 fflush(stderr);
00288 delete linea;
00289 return FALSE;
00290 }
00291
00292
00293 char *ptr, *qtr;
00294 LISTA <char *> tokens;
00295
00296 for ( ptr = strtok(linea, " \t\n"); ptr; ptr = strtok(NULL, " \t\n") ) {
00297 qtr = new char[strlen(ptr)+1];
00298 strcpy(qtr, ptr);
00299 tokens.anx(qtr);
00300 }
00301 delete linea;
00302
00303
00304 LISTA <char *> tokens_no_autonomos;
00305 BOOLEAN retorno;
00306
00307 for ( i = 0; i < tokens.tam(); i++ ) {
00308
00309 tokens_no_autonomos.anx(tokens[i]);
00310 }
00311 retorno = leer(&tokens_no_autonomos);
00312
00313
00314 for ( i = 0; i < tokens.tam(); i++ ) {
00315 delete tokens[i];
00316 }
00317 tokens.elim();
00318
00319 return retorno;
00320 }
00321
00322 void
00323 EXPRESION_REGULAR::imprimir(void)
00324 {
00325 switch ( tipo ) {
00326 case RA_CONSTANTE:
00327 printf("%.2f", valor);
00328 break;
00329 case RA_VARIABLE:
00330 printf("%s", nombre_variable);
00331 break;
00332 case OP_NEGACION:
00333 printf("- (");
00334 Der->imprimir();
00335 printf(")");
00336 break;
00337 case OP_SUMA:
00338 printf("("); Izq->imprimir(); printf(")");
00339 printf(" + ");
00340 printf("("); Der->imprimir(); printf(")");
00341 break;
00342 case OP_RESTA:
00343 printf("("); Izq->imprimir(); printf(")");
00344 printf(" - ");
00345 printf("("); Der->imprimir(); printf(")");
00346 break;
00347 case OP_MULTIPLICACION:
00348 printf("("); Izq->imprimir(); printf(")");
00349 printf(" * ");
00350 printf("("); Der->imprimir(); printf(")");
00351 break;
00352 case OP_DIVISION:
00353 printf("("); Izq->imprimir(); printf(")");
00354 printf(" / ");
00355 printf("("); Der->imprimir(); printf(")");
00356 break;
00357 case OP_EXPONENTE:
00358 printf("("); Izq->imprimir(); printf(")");
00359 printf(" ^ ");
00360 printf("("); Der->imprimir(); printf(")");
00361 break;
00362 case FN_SIN:
00363 printf("sin("); Der->imprimir(); printf(")");
00364 break;
00365 case FN_COS:
00366 printf("cos("); Der->imprimir(); printf(")");
00367 break;
00368 case FN_LOG:
00369 printf("log("); Der->imprimir(); printf(")");
00370 break;
00371 default: printf("{MA_ERROR}"); break;
00372 }
00373 fflush(stdout);
00374 }
00375
00376 double
00377 EXPRESION_REGULAR::evaluar(double t)
00378 {
00379 ultimo_t = t;
00380 switch ( tipo ) {
00381 case RA_CONSTANTE:
00382 return valor;
00383 case RA_VARIABLE:
00384
00385 return t;
00386 case OP_NEGACION:
00387 return Der->evaluar(t) * (-1);
00388 case OP_SUMA:
00389 return Izq->evaluar(t) + Der->evaluar(t);
00390 case OP_RESTA:
00391 return Izq->evaluar(t) - Der->evaluar(t);
00392 case OP_MULTIPLICACION:
00393 return Izq->evaluar(t) * Der->evaluar(t);
00394 case OP_DIVISION:
00395 return Izq->evaluar(t) / Der->evaluar(t);
00396 case OP_EXPONENTE:
00397 return pow(Izq->evaluar(t), Der->evaluar(t));
00398 case FN_SIN:
00399 return sin(Der->evaluar(t));
00400 case FN_COS:
00401 return cos(Der->evaluar(t));
00402 case FN_LOG:
00403 return log(Der->evaluar(t));
00404 default: break;
00405 }
00406 return 666;
00407 }
00408
00409
00410
00411
00412