Annotation of capa/capa51/pProj/capaUnit.c, revision 1.1
1.1 ! albertel 1:
! 2: /* =||>|===================== capaUnit.c =====================|<||= */
! 3: /* created by Isaac Tsai 1997 */
! 4: /* copyrighted by Isaac Tsai 1997, 1998, 1999 */
! 5: /* =||>|========================================================|<||= */
! 6: #include <stdio.h> /* fopen() */
! 7: #include <stdlib.h>
! 8: #include <ctype.h> /* isalnum() */
! 9: #include <string.h>
! 10: #include <math.h>
! 11:
! 12: #include "capaParser.h"
! 13:
! 14: int PrefixTbl[QUARTER_K];
! 15: int BaseUnitcnt;
! 16: double CScale[BASEUNIT_LIMIT];
! 17: double CExp[BASEUNIT_LIMIT];
! 18: char CSymb[BASEUNIT_LIMIT][SYMBOL_MAXLEN];
! 19: Unit_t *UnitTree_p;
! 20: double MinSquared;
! 21: Unit_t *MinSquaredUnit_p;
! 22: Unit_t *InqueryUnit_p;
! 23: double *TmpAexp, *TmpBexp;
! 24: Unit_t *EquivUnit[BASEUNIT_LIMIT];
! 25: double MinValue[BASEUNIT_LIMIT];
! 26: int EquivUnitCnt;
! 27: char Sbuf[ONE_K_SIZE];
! 28: int Sidx;
! 29: Unit_t *Pstack[ONE_K_SIZE];
! 30: int Ptopidx;
! 31: int gUnitError;
! 32:
! 33: FILE *ufp;
! 34:
! 35: /* ==================================================================== */
! 36: void c_ignorewhite(FILE *f) /* ignore white spaces from a file stream */
! 37: {
! 38: register int c;
! 39: register int ok;
! 40:
! 41: ok = 0;
! 42: do {
! 43: do { c = getc(f);
! 44: } while ( isspace(c) );
! 45: ungetc(c,f);
! 46: if (c == '#') {
! 47: while (getc(f) != '\n');
! 48: } else ok = 1;
! 49: } while( ! ok);
! 50: }
! 51:
! 52: int c_getint(FILE *f) /* returns an integer from the file stream */
! 53: {
! 54: int c;
! 55: int value;
! 56:
! 57: c_ignorewhite(f);
! 58: c = fgetc(f);
! 59: if (!isdigit(c)) {
! 60: fprintf(stderr,"Error: Expected digit, got %c\n", c);
! 61: exit(-1);
! 62: }
! 63: ungetc(c,f);
! 64: fscanf(f,"%d", &value);
! 65: return(value);
! 66: }
! 67: int c_getsec_range(FILE *f,int *low,int *high)
! 68: {
! 69: int c;
! 70: int tmp, result;
! 71:
! 72: c_ignorewhite(f);
! 73: c = fgetc(f);
! 74: if( c == '[' ) { /* specify a range of sections */
! 75: do { c = getc(f); } while ( isspace(c) );
! 76: if (!isdigit(c)) {
! 77: fprintf(stderr,"Error in section range format, expecting a number.\n");
! 78: result = -1;
! 79: return (result);
! 80: }
! 81: ungetc(c,f);
! 82: fscanf(f,"%d", low);
! 83: do { c = getc(f); } while ( isspace(c) );
! 84: if( c == ',' ) {
! 85: do { c = getc(f); } while ( isspace(c) );
! 86: if (!isdigit(c)) {
! 87: fprintf(stderr,"Error in section range format, expecting a number.\n");
! 88: result = -1;
! 89: return (result);
! 90: }
! 91: ungetc(c,f);
! 92: fscanf(f,"%d", high);
! 93: do { c = getc(f); } while ( isspace(c) );
! 94: if( c == ']' ) {
! 95: if( *high < *low ) {
! 96: tmp= *high; *high = *low; *low =tmp;
! 97: }
! 98: if(*low <=0) {
! 99: *low = 1;
! 100: }
! 101: if(*high <=0) {
! 102: *high =1;
! 103: }
! 104: /* printf("Section range=>[%d,%d]\n",*low,*high); */
! 105: result = 2;
! 106: }
! 107: } else { /* no , specified */
! 108: result = -1;
! 109: return (result);
! 110: }
! 111: } else { /* specify a section only */
! 112: if (!isdigit(c)) {
! 113: fprintf(stderr,"Error: Expected digit, got %c\n", c);
! 114: result = -1;
! 115: return (result);
! 116: }
! 117: ungetc(c,f);
! 118: fscanf(f,"%d", low);
! 119: result = 1;
! 120: }
! 121: return (result);
! 122: }
! 123:
! 124: double c_getdouble(FILE *f)
! 125: {
! 126: int c;
! 127: double value;
! 128:
! 129: c_ignorewhite(f);
! 130: c = fgetc(f);
! 131: if (!isdigit(c)) {
! 132: fprintf(stderr,"Error: Expected digit, got %c\n", c);
! 133: exit(-1);
! 134: }
! 135: ungetc(c,f);
! 136: fscanf(f,"%lf", &value);
! 137: return(value);
! 138: }
! 139:
! 140: /* read until encountered an unrecognizable char */
! 141: /* space, #, anything other than alphanum, {}-^_ */
! 142: char *c_getword(FILE *f)
! 143: {
! 144: register int c;
! 145: register int idx;
! 146: char tmp_string[ONE_K];
! 147: char *new_string;
! 148:
! 149: idx = 0;
! 150: c_ignorewhite(f);
! 151: do { c = getc(f);
! 152: tmp_string[idx] = c;
! 153: idx++;
! 154: } while (isalnum(c) || c == '{' || c == '}' || c == '-' ||
! 155: c == '^' || c == '_' );
! 156: ungetc(c,f); idx--;
! 157: tmp_string[idx] = 0;
! 158: new_string = (char *)malloc( (idx+1)*sizeof(char) );
! 159: strncpy(new_string,tmp_string, (idx+1) );
! 160:
! 161: return (new_string);
! 162: }
! 163: /* read until encountered a newline, # */
! 164: char *c_getstring(FILE *f)
! 165: {
! 166: register int c;
! 167: register int idx;
! 168: char tmp_string[1024];
! 169: char *new_string;
! 170:
! 171: idx = 0;
! 172: c_ignorewhite(f);
! 173: do { c = getc(f);
! 174: tmp_string[idx] = c;
! 175: idx++;
! 176: } while (isalnum(c) || c == '{' || c == '}' || c == '-' ||
! 177: c == '^' || c == ' ' || c == ',' || c == ';' ||
! 178: c == '.' || c == '(' || c == ')' || c == '=' ||
! 179: c == '+' || c == '*' || c == '/' );
! 180: ungetc(c,f); idx--;
! 181: tmp_string[idx] = 0;
! 182: c = tmp_string[idx-1];
! 183: while( c == ' ') { /* get rid of trailing white space */
! 184: idx--;
! 185: c = tmp_string[idx-1];
! 186: }
! 187: tmp_string[idx] = 0;
! 188: new_string = (char *)malloc( (idx+1)*sizeof(char) );
! 189: strncpy(new_string,tmp_string, (idx+1) );
! 190:
! 191: return (new_string);
! 192: }
! 193: char *c_getcomment(FILE *f)
! 194: {
! 195: register int c;
! 196: register int idx;
! 197: char tmp_string[ONE_K];
! 198: char *new_string;
! 199:
! 200: idx = 0;
! 201: while (getc(f) != '#');
! 202: while ((c = getc(f)) == ' '); ungetc(c,f);
! 203: do { c = getc(f);
! 204: tmp_string[idx] = c;
! 205: idx++;
! 206: } while ( isprint(c) );
! 207: /*
! 208: } while (isalnum(c) || c == '{' || c == '}' || c == '-' ||
! 209: c == '^' || c == ' ' || c == ',' || c == ';' ||
! 210: c == '.' || c == '(' || c == ')' || c == '=' );
! 211: */
! 212: ungetc(c,f); idx--;
! 213: tmp_string[idx] = 0;
! 214: c = tmp_string[idx-1];
! 215: while( c == ' ') { /* get rid of trailing white space */
! 216: idx--;
! 217: c = tmp_string[idx-1];
! 218: }
! 219: tmp_string[idx] = 0;
! 220: new_string = (char *)malloc( (idx+1)*sizeof(char) );
! 221: strncpy(new_string,tmp_string, (idx+1) );
! 222:
! 223: return (new_string);
! 224: }
! 225: void c_moveto_unit(FILE *f)
! 226: {
! 227: register int c;
! 228: register int ok;
! 229:
! 230: ok = 0;
! 231: do {
! 232: do { c = getc(f);
! 233: } while (c != '<' );
! 234: c = getc(f);
! 235: if (c == '<') {
! 236: ungetc(c,f); ungetc(c,f); ok=1;
! 237: }
! 238: } while( ! ok);
! 239: }
! 240:
! 241: int c_gettype(FILE *f)
! 242: {
! 243: register int c;
! 244: register int idx;
! 245: char tmp_string[ONE_K];
! 246: char new_string[ONE_K];
! 247:
! 248: idx = 0;
! 249: PRESTART:
! 250: c_ignorewhite(f);
! 251: while ((c=getc(f)) != '<') { if ( (char)c==(char)EOF ) return U_UNKNOWN; }
! 252: c = getc(f);
! 253: if( c == '<' ) {
! 254: c_ignorewhite(f);
! 255: PREEND:
! 256: do { c = getc(f);
! 257: tmp_string[idx] = toupper(c);
! 258: idx++;
! 259: } while ( c != '>' );
! 260: c = getc(f);
! 261: if( c == '>' ) {
! 262: idx--;
! 263: tmp_string[idx] = 0;
! 264: c = tmp_string[idx-1];
! 265: while( c == ' ') { /* get rid of trailing white space */
! 266: idx--;
! 267: c = tmp_string[idx-1];
! 268: }
! 269: tmp_string[idx] = 0;
! 270: strncpy(new_string,tmp_string, (idx+1) );
! 271: } else {
! 272: ungetc(c,f);
! 273: goto PREEND;
! 274: }
! 275: } else {
! 276: goto PRESTART;
! 277: }
! 278: if( !strcmp(new_string,"BASE UNIT") ) {
! 279: return (U_BASE);
! 280: }
! 281: if( strcmp(new_string, "DERIVED UNIT") == 0 ) {
! 282: return (U_DERIVED);
! 283: }
! 284: if( strcmp(new_string, "PREFIX") == 0 ) {
! 285: return (U_PREFIX);
! 286: }
! 287: if( strcmp(new_string, "CONSTANTS") == 0 ) {
! 288: return (U_CONSTANT);
! 289: }
! 290: if( strcasecmp(new_string, "DEFAULTS") == 0 ) {
! 291: return (U_DEFAULT);
! 292: }
! 293: return (U_UNKNOWN);
! 294:
! 295: }
! 296:
! 297: /* =================================================================== */
! 298: /* =================================================================== */
! 299: /* returns: 0 success */
! 300: /* 1 the first units string u1_str could not be reduce to a valid unit */
! 301: /* 2 the second units string could not be reduced to a valid unit */
! 302: int
! 303: u_convert_unit(char *u1_str,char *u2_str,double *ratio)
! 304: {
! 305: Unit_t *ap, *bp;
! 306: int result=0;
! 307:
! 308: while( isspace(*u1_str) ) u1_str++;
! 309: while( isspace(*u2_str) ) u2_str++;
! 310: bp = parse_unit_expr(u2_str);
! 311: Ptopidx=0;
! 312: postwalk_utree(bp);
! 313: if( Ptopidx == 1 ) {
! 314: simplify_unit(Pstack[Ptopidx]);
! 315: bp = Pstack[Ptopidx];
! 316: /* print_unit_t(bp); */
! 317: ap = parse_unit_expr(u1_str);
! 318: Ptopidx=0;
! 319: postwalk_utree(ap);
! 320: if( Ptopidx == 1 ) {
! 321: simplify_unit(Pstack[Ptopidx]);
! 322: /* print_unit_t(Pstack[Ptopidx]); */
! 323: if( (Pstack[Ptopidx]->u_count != 0) ||
! 324: (Pstack[Ptopidx]->u_count == bp->u_count) ) { /* has unit */
! 325: *ratio = units_ratio(Pstack[Ptopidx], bp);
! 326: } else {
! 327: result = 1;
! 328: }
! 329: }
! 330: free_utree(ap);
! 331: } else {
! 332: result = 2;
! 333: }
! 334: free_utree(bp);
! 335: return (result);
! 336: }
! 337:
! 338: /* =================================================================== */
! 339:
! 340:
! 341:
! 342: Unit_t *
! 343: u_find_symb (char *name, Unit_t *t, int *result)
! 344: {
! 345:
! 346: if (t == NULL) return t;
! 347:
! 348: for (;;) {
! 349: if ( comp_unit_symb(name,t->u_symbol) < 0 ) {
! 350: if (t->u_left == NULL) {
! 351: /* printf("L not found\n"); */
! 352: *result = 0;
! 353: break;
! 354: }
! 355: t = t->u_left;
! 356: } else if ( comp_unit_symb(name,t->u_symbol) > 0 ) {
! 357: if (t->u_right == NULL) {
! 358: /* printf("R not found\n"); */
! 359: *result = 0;
! 360: break;
! 361: }
! 362: t = t->u_right;
! 363: } else {
! 364: *result = 1;
! 365: break;
! 366: }
! 367: }
! 368: return t;
! 369: }
! 370: /* ------------------------------------------------------------- */
! 371: /* use the input unit_t's element list to locate the min squared */
! 372: /* error fit of the unit tree */
! 373: /* report either exact fit or approx */
! 374:
! 375: void
! 376: u_find_name(Unit_t *t)
! 377: {
! 378: int ii;
! 379: Unit_E *eu_p;
! 380:
! 381: MinSquared = FLT_MAX;
! 382: EquivUnitCnt=0;
! 383: InqueryUnit_p = t;
! 384: /* printf("INQ[[%s,%s,%d]]\n", U_SYMB(t), U_NAME(t),U_COUNT(t)); */
! 385: TmpAexp = (double *)capa_malloc(BaseUnitcnt,sizeof(double));
! 386: TmpBexp = (double *)capa_malloc(BaseUnitcnt,sizeof(double));
! 387: for(ii=0;ii<BaseUnitcnt;ii++) {
! 388: TmpAexp[ii] = 0.0;
! 389: }
! 390: if( t->u_count > 0 ) {
! 391: for(eu_p = t->u_list; eu_p; eu_p = eu_p->ue_nextp) {
! 392: TmpAexp[eu_p->ue_index] = eu_p->ue_exp;
! 393: /* printf("(%d)^(%g) ",eu_p->ue_index,TmpAexp[eu_p->ue_exp]); */
! 394: }
! 395: /* printf("\n"); */
! 396: }
! 397: inorder_diff(UnitTree_p);
! 398: /*capa_mfree((char *)TmpAexp); capa_mfree((char *)TmpBexp);*/
! 399:
! 400: }
! 401:
! 402: void
! 403: print_matches(Unit_t *t)
! 404: {
! 405: double scale, factor;
! 406: Unit_t *tmp_p;
! 407: int ii;
! 408:
! 409: scale = t->u_scale;
! 410: if( MinSquared == 0.0 ) { /* exact match */
! 411: if( EquivUnitCnt > 0 ) {
! 412: printf(" Entered unit is equivalent to:\n");
! 413: for(ii=0;ii<EquivUnitCnt;ii++) {
! 414: tmp_p = EquivUnit[ii];
! 415: if( MinSquared == MinValue[ii] ) {
! 416: if( tmp_p->u_type == U_BASE ) { /* if there is a base unit */
! 417: MinSquaredUnit_p = tmp_p;
! 418: }
! 419: factor = scale / tmp_p->u_scale;
! 420: printf(" <<%g %s>>", factor,U_SYMB(tmp_p));
! 421: }
! 422: }
! 423: printf("\n");
! 424:
! 425: }
! 426: } else { /* no exact match */
! 427: if( EquivUnitCnt > 0 ) {
! 428: printf(" Entered unit is approximated by:\n");
! 429: for(ii=0;ii<EquivUnitCnt;ii++) {
! 430: tmp_p = EquivUnit[ii];
! 431: if( MinSquared == MinValue[ii] ) {
! 432: printf(" <<%s>> ", U_SYMB(tmp_p) );
! 433: }
! 434: }
! 435: printf("\n");
! 436: }
! 437: }
! 438: }
! 439:
! 440: /* ------------------------------------ */
! 441: double
! 442: u_squared_diff(Unit_t *a, Unit_t *b)
! 443: {
! 444: double result;
! 445: double squared_diff = 0.0;
! 446: int ii;
! 447: Unit_E *eu_p;
! 448:
! 449:
! 450: for(ii=0;ii<BaseUnitcnt;ii++) {
! 451: TmpAexp[ii] = 0.0;
! 452: TmpBexp[ii] = 0.0;
! 453: }
! 454: if( a->u_count > 0 ) {
! 455: for(eu_p= a->u_list; eu_p; eu_p = eu_p->ue_nextp) {
! 456: TmpAexp[eu_p->ue_index] = eu_p->ue_exp;
! 457: }
! 458: }
! 459: if( b->u_count > 0 ) {
! 460: for(eu_p= b->u_list; eu_p; eu_p = eu_p->ue_nextp) {
! 461: TmpBexp[eu_p->ue_index] = eu_p->ue_exp;
! 462: /* printf("Exp[%d]=%g ",ii,TmpBexp[ii]); */
! 463: }
! 464: /* printf("\n"); */
! 465: }
! 466: for(ii=0;ii<BaseUnitcnt;ii++) {
! 467: result = TmpAexp[ii] - TmpBexp[ii];
! 468: squared_diff = squared_diff + result*result;
! 469: }
! 470:
! 471: return (squared_diff);
! 472: }
! 473:
! 474: double
! 475: u_sq_diff(Unit_t *b)
! 476: {
! 477: double result;
! 478: double squared_diff = 0.0;
! 479: int ii;
! 480: Unit_E *eu_p;
! 481:
! 482:
! 483: for(ii=0;ii<BaseUnitcnt;ii++) {
! 484: TmpBexp[ii] = 0.0;
! 485: }
! 486: if( b->u_count > 0 ) {
! 487: for(eu_p= b->u_list; eu_p; eu_p = eu_p->ue_nextp) {
! 488: TmpBexp[eu_p->ue_index] = eu_p->ue_exp;
! 489: /* printf("Exp[%d]=%g ",ii,TmpBexp[ii]); */
! 490: }
! 491: /* printf("\n"); */
! 492: } else if( b->u_type == U_BASE ) {
! 493: TmpBexp[b->u_index] = 1.0;
! 494: }
! 495: for(ii=0;ii<BaseUnitcnt;ii++) {
! 496: result = TmpAexp[ii] - TmpBexp[ii];
! 497: squared_diff = squared_diff + result*result;
! 498: }
! 499:
! 500: return (squared_diff);
! 501:
! 502: }
! 503: /* ------------------------------------ */
! 504:
! 505: int
! 506: inorder_diff(node_p) Unit_t *node_p;
! 507: {
! 508: int result;
! 509: double sq_diff=0.0;
! 510:
! 511: if( node_p == NULL ) return (1);
! 512:
! 513: result = inorder_diff(U_LEFT(node_p));
! 514: if( result ) {
! 515: sq_diff = u_sq_diff(node_p);
! 516: /*
! 517: printf("DIFF [%s,%s,%d] - [%s,%s,%d] = %g\n",
! 518: U_SYMB(InqueryUnit_p), U_NAME(InqueryUnit_p),U_COUNT(InqueryUnit_p),
! 519: U_SYMB(node_p), U_NAME(node_p),U_COUNT(node_p),sq_diff);
! 520: */
! 521: if( MinSquared > sq_diff) {
! 522: MinSquaredUnit_p = node_p;
! 523: MinSquared = sq_diff;
! 524: } else if ( MinSquared == sq_diff) {
! 525: EquivUnit[EquivUnitCnt] = node_p;
! 526: MinValue[EquivUnitCnt] = sq_diff;
! 527: EquivUnitCnt++;
! 528: }
! 529: }
! 530: result = inorder_diff(U_RIGHT(node_p));
! 531:
! 532: return (result);
! 533: }
! 534:
! 535:
! 536: int
! 537: alphaorder_utree(node_p) Unit_t *node_p;
! 538: {
! 539: int result;
! 540:
! 541: if( node_p == NULL ) return (1);
! 542:
! 543: result = alphaorder_utree(U_LEFT(node_p));
! 544: if( result ) printf(" (%s,%s)\n", U_SYMB(node_p), U_NAME(node_p) );
! 545: result = alphaorder_utree(U_RIGHT(node_p));
! 546:
! 547: return (result);
! 548: }
! 549:
! 550: int
! 551: w_alphaorder_utree(node_p) Unit_t *node_p;
! 552: {
! 553: int result;
! 554:
! 555: if( node_p == NULL ) return (1);
! 556:
! 557: result = alphaorder_utree(U_LEFT(node_p));
! 558: if( result ) {
! 559: printf(" (%s,%s)\n", U_SYMB(node_p), U_NAME(node_p) );
! 560: }
! 561: result = alphaorder_utree(U_RIGHT(node_p));
! 562:
! 563: return (result);
! 564: }
! 565:
! 566: /* --------------------------------------------------------------------- */
! 567: void
! 568: print_unit_tree(int mode)
! 569: {
! 570: if( mode == 1 ) {
! 571: alphaorder_utree(UnitTree_p);
! 572: } else {
! 573: w_alphaorder_utree(UnitTree_p);
! 574: }
! 575: }
! 576:
! 577:
! 578: int
! 579: preorder_utree(node_p) Unit_t *node_p;
! 580: {
! 581: int result;
! 582:
! 583: if( node_p == NULL ) return (1);
! 584: printf("Preorder=[[%s,%s,%d]]\n", U_SYMB(node_p), U_NAME(node_p),U_COUNT(node_p));
! 585: result = preorder_utree(U_LEFT(node_p));
! 586: if( result ) result = preorder_utree(U_RIGHT(node_p));
! 587: return (result);
! 588: }
! 589: int
! 590: inorder_utree(node_p) Unit_t *node_p;
! 591: {
! 592: int result;
! 593:
! 594: if( node_p == NULL ) return (1);
! 595:
! 596: result = inorder_utree(U_LEFT(node_p));
! 597: if( result ) printf("INorder=[[%s,%s,%d]]\n",
! 598: U_SYMB(node_p), U_NAME(node_p),U_COUNT(node_p));
! 599: result = inorder_utree(U_RIGHT(node_p));
! 600:
! 601: return (result);
! 602: }
! 603: int
! 604: postorder_utree(node_p) Unit_t *node_p;
! 605: {
! 606: int result;
! 607:
! 608: if( node_p == NULL ) return (1);
! 609:
! 610: result = postorder_utree(U_LEFT(node_p));
! 611: if( result ) result = postorder_utree(U_RIGHT(node_p));
! 612: if( result ) {
! 613: switch(U_TYPE(node_p)) {
! 614: case U_DERIVED: print_unit_t(node_p);
! 615: break;
! 616: case U_CONSTANT: printf("(%g)",U_SCALE(node_p));
! 617: break;
! 618: case U_OP_POWER: printf("^");
! 619: break;
! 620: case U_OP_TIMES: printf("*");
! 621: break;
! 622: case U_OP_PLUS: printf("+");
! 623: break;
! 624: case U_OP_MINUS: printf("-");
! 625: break;
! 626: case U_OP_DIVIDE: printf("/");
! 627: break;
! 628: default: printf("()");
! 629: break;
! 630: }
! 631: }
! 632: return (result);
! 633: }
! 634:
! 635: int
! 636: postwalk_utree(Unit_t *n_p)
! 637: {
! 638: int result;
! 639:
! 640: if( n_p == NULL ) return (1);
! 641:
! 642: result = postwalk_utree(U_LEFT(n_p));
! 643: if( result ) result = postwalk_utree(U_RIGHT(n_p));
! 644: if( result ) {
! 645: switch(U_TYPE(n_p)) {
! 646: case U_DERIVED: Ptopidx++; Pstack[Ptopidx] = n_p; /* push into stack */
! 647: break;
! 648: case U_CONSTANT: Ptopidx++; Pstack[Ptopidx] = n_p; /* push into stack */
! 649: break;
! 650: case U_OP_POWER: printf("^");
! 651: break;
! 652: case U_OP_TIMES: process_op(U_OP_TIMES); /* process operator */
! 653: break;
! 654: case U_OP_PLUS: printf("+");
! 655: break;
! 656: case U_OP_MINUS: printf("-");
! 657: break;
! 658: case U_OP_DIVIDE: process_op(U_OP_DIVIDE); /* process operator */
! 659: break;
! 660: default: printf("()");
! 661: break;
! 662: }
! 663: }
! 664: return (result);
! 665: }
! 666:
! 667: void
! 668: process_op(int op)
! 669: {
! 670: Unit_t *ap, *bp;
! 671: double exp_scale;
! 672: int no_error=1;
! 673:
! 674: bp = Pstack[Ptopidx--];
! 675: ap = Pstack[Ptopidx--];
! 676:
! 677: switch(op) {
! 678: case U_OP_TIMES: exp_scale = 1.0; break;
! 679: case U_OP_DIVIDE: exp_scale = -1.0; break;
! 680: case U_OP_PLUS:
! 681: case U_OP_MINUS: no_error = u_pm_op(ap,bp,op);
! 682: if(no_error) {
! 683: Ptopidx++;
! 684: Pstack[Ptopidx] = ap;
! 685: }
! 686: break;
! 687: default: no_error=0;
! 688: printf("No such op on the parse tree!\n");
! 689: break;
! 690: }
! 691: if(no_error) {
! 692: u_copy_unit(ap, bp, exp_scale);
! 693: Ptopidx++;
! 694: Pstack[Ptopidx] = ap;
! 695: }
! 696: }
! 697:
! 698: void
! 699: process_utree(Unit_t *t)
! 700: {
! 701: Ptopidx=0;
! 702: postwalk_utree(t);
! 703: if( Ptopidx == 1 ) {
! 704: /* printf("Correctly parsed!\n"); */
! 705: printf("Unit:%s\n",Sbuf);
! 706: simplify_unit(Pstack[Ptopidx]);
! 707: Pstack[Ptopidx]->u_symbol[0]='\0';
! 708: /*sprintf(Pstack[Ptopidx]->u_symbol,"");*/
! 709: print_unit_t(Pstack[Ptopidx]);
! 710: u_find_name(Pstack[Ptopidx]);
! 711: print_matches(Pstack[Ptopidx]);
! 712: free_utree(t);
! 713: }
! 714: }
! 715:
! 716: /* ============================================================== */
! 717: /* called from capaCommon.c */
! 718: /* */
! 719: /* UNIT_FAIL */
! 720: /* NO_UNIT */
! 721: /* result: UNIT_OK correct */
! 722: /* */
! 723: /* -------------------------------------------------------------- */
! 724: int check_correct_unit(char *u_symb,Unit_t *t,double *scale)
! 725: {
! 726: Unit_t *ap;
! 727: int result=UNIT_OK;
! 728:
! 729: #ifdef UNIT_DBUG
! 730: if ((ufp=fopen("unit.DBUG","a"))==NULL) { fprintf(stderr,"Error: can't open login debug\n"); return; }
! 731: #endif
! 732:
! 733: while( isspace(*u_symb) ) u_symb++;
! 734: ap = parse_unit_expr(u_symb);
! 735: Ptopidx=0;
! 736: postwalk_utree(ap);
! 737: #ifdef UNIT_DBUG
! 738: fprintf(ufp,"Ptopidx %d\n",Ptopidx);
! 739: #endif
! 740: if( Ptopidx == 1 ) {
! 741: simplify_unit(Pstack[Ptopidx]);
! 742:
! 743: if( (Pstack[Ptopidx]->u_count != 0) ||
! 744: (Pstack[Ptopidx]->u_count == t->u_count) ) { /* has unit */
! 745: *scale = units_ratio(Pstack[Ptopidx], t);
! 746: if( *scale == 0.0 ) {
! 747: result = UNIT_FAIL;
! 748: }
! 749: free_utree(ap);
! 750: } else {
! 751: result = UNIT_FAIL;
! 752: }
! 753: } else { /* invalid unit representation */
! 754: result = UNIT_FAIL;
! 755: }
! 756: #ifdef UNIT_DBUG
! 757: fclose(ufp);
! 758: #endif
! 759: return (result);
! 760: }
! 761:
! 762: /* ============================================================= */
! 763: int
! 764: free_units()
! 765: {
! 766: free_utree(UnitTree_p);
! 767: UnitTree_p=NULL;
! 768: return 0;
! 769: }
! 770:
! 771: int
! 772: free_utree(Unit_t *t)
! 773: {
! 774: int result=1;
! 775:
! 776: if( t == NULL ) return (1);
! 777: u_postfree(t);
! 778: t=NULL;
! 779:
! 780: return (result);
! 781: }
! 782:
! 783:
! 784: int
! 785: u_postfree(Unit_t *t)
! 786: {
! 787: int result;
! 788:
! 789: if( t == NULL ) return (1);
! 790:
! 791: result = u_postfree(U_LEFT(t));
! 792: if( result ) result = u_postfree(U_RIGHT(t));
! 793: if( result ) {
! 794: if( t->u_comment ) {
! 795: capa_mfree((char *)t->u_comment);
! 796: }
! 797: freelist_unit_e(t->u_list);
! 798: capa_mfree((char *)t);
! 799: }
! 800: return (result);
! 801: }
! 802:
! 803:
! 804: void
! 805: print_unit_t(Unit_t *t)
! 806: {
! 807: Unit_E *ue_p;
! 808:
! 809: /* printf(" Unit::[%s,%d]= %g * ", t->u_symbol,t->u_count,t->u_scale); */
! 810: printf(" Unit::[%s] = %g * ", t->u_symbol, t->u_scale);
! 811: for(ue_p=t->u_list; ue_p ; ue_p = ue_p->ue_nextp) {
! 812: /*
! 813: printf("<%s,%d,%g,%g> ",ue_p->ue_symbol,ue_p->ue_index,ue_p->ue_scale,ue_p->ue_exp);
! 814: */
! 815: printf("(%g*%s^%g) ",ue_p->ue_scale,ue_p->ue_symbol,ue_p->ue_exp);
! 816: }
! 817: printf("\n");
! 818:
! 819: }
! 820: /* ----------------------------------------------------------- */
! 821: /* copy the Unit_E linked list from b_p->u_list to a_p->u_list */
! 822: /* create some Unit_E nodes in a_p->u_list if needed and */
! 823: /* leave b_p->u_list intact */
! 824: /* a_p->u_scale is multiplied by pow(b_p->u_scale,exp_scale) */
! 825: /* ----------------------------------------------------------- */
! 826: void
! 827: u_copy_unit(Unit_t *a_p, Unit_t *b_p, double exp_scale)
! 828: {
! 829: Unit_E *oe_p, *ne_p, *last_p;
! 830: int ii;
! 831: double scale;
! 832:
! 833: if( a_p->u_count > 0 ) {
! 834: for(last_p = a_p->u_list; last_p->ue_nextp; last_p = last_p->ue_nextp) { }
! 835: } else {
! 836: a_p->u_list = last_p = NULL;
! 837: }
! 838: if( b_p->u_count > 0 ) {
! 839: oe_p = b_p->u_list;
! 840: for(ii=0;ii<b_p->u_count;ii++) {
! 841: ne_p = (Unit_E *) capa_malloc(1, sizeof(Unit_E)); /* *** */
! 842: ne_p->ue_scale = oe_p->ue_scale;
! 843: ne_p->ue_exp = oe_p->ue_exp * exp_scale;
! 844: ne_p->ue_index = oe_p->ue_index;
! 845: strcpy(ne_p->ue_symbol, oe_p->ue_symbol);
! 846: oe_p = oe_p->ue_nextp;
! 847: if( last_p == NULL ) {
! 848: a_p->u_list = ne_p;
! 849: } else {
! 850: last_p->ue_nextp = ne_p;
! 851: }
! 852: last_p = ne_p;
! 853: a_p->u_count++;
! 854: }
! 855: scale = pow(b_p->u_scale, exp_scale);
! 856: a_p->u_scale = a_p->u_scale * scale;
! 857: /* printf("Found scale=%g=%g\n",a_p->u_scale,b_p->u_scale); */
! 858: } else {
! 859: if( b_p->u_type == U_BASE || b_p->u_type == U_DERIVED) {
! 860: /* *b_p is a base unit, so create a one element unit */
! 861: ne_p = (Unit_E *) capa_malloc(1, sizeof(Unit_E)); /* *** */
! 862: ne_p->ue_scale = b_p->u_scale;
! 863: ne_p->ue_exp = exp_scale;
! 864: ne_p->ue_index = b_p->u_index;
! 865: strcpy(ne_p->ue_symbol, b_p->u_symbol);
! 866: if( last_p == NULL ) {
! 867: a_p->u_list = ne_p;
! 868: } else {
! 869: last_p->ue_nextp = ne_p;
! 870: }
! 871: last_p = ne_p;
! 872: a_p->u_count++;
! 873: } else if( b_p->u_type == U_CONSTANT ) {
! 874: scale = pow(b_p->u_scale, exp_scale);
! 875: a_p->u_scale = a_p->u_scale * scale;
! 876: } else {
! 877: printf("This node has no u_e list and Type unknown\n");
! 878: }
! 879: }
! 880: }
! 881: int
! 882: u_pm_op(Unit_t *a_p, Unit_t *b_p, int op)
! 883: {
! 884: int result=0;
! 885:
! 886: if( a_p->u_count > 0 || b_p->u_count > 0 ) {
! 887: printf(" cannot add or sub units at this moment\n");
! 888: return result;
! 889: }
! 890: if( op == U_OP_PLUS ) {
! 891: a_p->u_scale = a_p->u_scale + b_p->u_scale;
! 892: } else {
! 893: a_p->u_scale = a_p->u_scale - b_p->u_scale;
! 894: }
! 895: return 1;
! 896: }
! 897:
! 898: int
! 899: u_parsepower(char *unit_str)
! 900: {
! 901: int exp, ii;
! 902: char *ch_p, exp_str[16];
! 903:
! 904: ch_p = unit_str;
! 905: while( isspace(*ch_p) ) { ch_p++; }
! 906: ii=0;
! 907: while( isdigit(*ch_p) ) {
! 908: ch_p++;
! 909: }
! 910: while( isspace(*ch_p) ) { ch_p++; }
! 911: if( *ch_p == '^' ) {
! 912: ch_p++;
! 913: }
! 914: while( isspace(*ch_p) ) { ch_p++; }
! 915: if( *ch_p == '{' ) {
! 916: ch_p++;
! 917: }
! 918: while( isspace(*ch_p) ) { ch_p++; }
! 919: ii=0;
! 920: while( isdigit(*ch_p) || *ch_p == '-' || *ch_p == '+' ) {
! 921: exp_str[ii++] = *ch_p;
! 922: ch_p++;
! 923: }
! 924: exp_str[ii]=0;
! 925: sscanf(exp_str,"%d", &exp);
! 926: return (exp);
! 927: }
! 928:
! 929: /* ------------------------------------------- */
! 930: /* scan a number of the form indicated below from the input buffer */
! 931: /* 1.234^{2.3} */
! 932: /* 1e */
! 933: double
! 934: s_scan_number(char *buf, int idx, int *r_idx)
! 935: {
! 936: double num;
! 937: float exp;
! 938: double result;
! 939: int ii=0;
! 940: char num_str[QUARTER_K];
! 941:
! 942: num_str[ii]=0;
! 943:
! 944: if( buf[idx] == '-' ) {
! 945: num_str[ii++] = '-';
! 946: idx++;
! 947: }
! 948: while( isdigit(buf[idx]) || buf[idx] == '.' ) {
! 949: num_str[ii++] = buf[idx];
! 950: idx++;
! 951: }
! 952: if( buf[idx] == 'E' || buf[idx] == 'e' ) {
! 953: if( buf[idx+1] == '-' || isdigit(buf[idx+1]) ) {
! 954: num_str[ii++] = buf[idx++];
! 955: num_str[ii++] = buf[idx++];
! 956: while( isdigit(buf[idx]) ) {
! 957: num_str[ii++] = buf[idx];
! 958: idx++;
! 959: }
! 960: }
! 961: }
! 962: num_str[ii] = 0; /* terminate the str */
! 963: sscanf(num_str,"%lg", &num);
! 964: /* printf("Scan number %s got %g\n",num_str, num); fflush(stdout); */
! 965: result = num;
! 966: if( buf[idx] == '^' ) {
! 967: idx++;
! 968: while( isspace(buf[idx]) ) { idx++; }
! 969: if( buf[idx] == '{' ) { /* need to scan for a matching right bracket */
! 970: idx++;
! 971: }
! 972: while( isspace(buf[idx]) ) { idx++; }
! 973: num_str[0]=0;
! 974: if( isdigit(buf[idx]) || buf[idx] == '+' || buf[idx] == '-' ) {
! 975: ii=0;
! 976: while( isdigit(buf[idx]) || buf[idx] == '.' || buf[idx] == '+' || buf[idx] == '-' ) {
! 977: num_str[ii++] = buf[idx];
! 978: idx++;
! 979: }
! 980: num_str[ii]=0;
! 981: }
! 982: while( isspace(buf[idx]) ) { idx++; }
! 983: if( buf[idx] == '}' ) {
! 984: idx++;
! 985: }
! 986: sscanf(num_str,"%f", &exp);
! 987: /* printf("Scan exp number %s got %g\n",num_str, exp); fflush(stdout); */
! 988:
! 989: result = pow(num, (double)exp);
! 990: /* printf("{%d^%d}=%g\n",num, exp,result); */
! 991: }
! 992: *r_idx = idx;
! 993: return (result);
! 994: }
! 995:
! 996:
! 997: double
! 998: s_scan_symbol(char *buf,char *symb_p,int idx, int *r_idx)
! 999: {
! 1000: char num_str[QUARTER_K];
! 1001: int ii=0;
! 1002: double r_exp=1.0;
! 1003:
! 1004: symb_p[0]=0;
! 1005: while( isalnum(buf[idx]) || buf[idx] == '_' ) {
! 1006: symb_p[ii++] = buf[idx];
! 1007: idx++;
! 1008: }
! 1009: symb_p[ii]=0;
! 1010:
! 1011: if( buf[idx] == '^' ) { /* look for either left bracket or a number */
! 1012: idx++;
! 1013: while( isspace(buf[idx]) ) { idx++; }
! 1014: if( buf[idx] == '{' ) { /* need to scan for a matching right bracket */
! 1015: idx++;
! 1016: }
! 1017: while( isspace(buf[idx]) ) { idx++; }
! 1018: if( isdigit(buf[idx]) || buf[idx] == '.' || buf[idx] == '+' || buf[idx] == '-' ) {
! 1019: ii=0; num_str[ii] = 0;
! 1020: while( isdigit(buf[idx]) || buf[idx] == '.' || buf[idx] == '+' || buf[idx] == '-' ) {
! 1021: num_str[ii++] = buf[idx];
! 1022: idx++;
! 1023: }
! 1024: num_str[ii]=0;
! 1025: }
! 1026: while( isspace(buf[idx]) ) { idx++; }
! 1027: if( buf[idx] == '}' ) {
! 1028: idx++;
! 1029: }
! 1030: sscanf(num_str,"%lg", &r_exp); /* power could be of type float */
! 1031: /* printf("[scan symb with power %s ^ %lg] ",symb_p, r_exp); fflush(stdout); */
! 1032: }
! 1033: *r_idx = idx;
! 1034: return (r_exp);
! 1035: }
! 1036:
! 1037: /* return: err_code 0 parsed ok */
! 1038: /* 1 symbol is of length 1, not found in the tree */
! 1039: /* 2 symbol not found in the tree */
! 1040: /* 3 symbol parsed as prefix symb, but symb not found */
! 1041: /* 4 symbol length is 0 or negative */
! 1042: int
! 1043: s_process_symb(char *symb_str,Unit_t *cu_p,double exp)
! 1044: {
! 1045: int len;
! 1046: Unit_t *au_p;
! 1047: int c_result;
! 1048: int ii;
! 1049: char tmp_str[ANSWER_STRING_LENG];
! 1050: int err_code = 0;
! 1051: double d_exp;
! 1052:
! 1053: len = strlen(symb_str);
! 1054: if( len > 0 ) {
! 1055: au_p = u_find_symb(symb_str, UnitTree_p, &c_result);
! 1056: if( c_result == 1 ) { /* if found, copy the definition over */
! 1057: u_copy_unit(cu_p, au_p, exp);
! 1058: } else {
! 1059: if( len > 1 ) {
! 1060: if( PrefixTbl[ (int)symb_str[0] ] != 0 ) { /* prefix is defined */
! 1061: for(ii=1;ii<len;ii++) {
! 1062: tmp_str[ii-1] = symb_str[ii];
! 1063: }
! 1064: tmp_str[len-1]=0;
! 1065: au_p = u_find_symb(tmp_str, UnitTree_p, &c_result);
! 1066: if( c_result == 1 ) {
! 1067: /* printf("[%s] ", tmp_str); */
! 1068: u_copy_unit(cu_p, au_p, exp);
! 1069: d_exp = (double)PrefixTbl[ (int)symb_str[0] ] * exp;
! 1070: cu_p->u_scale = cu_p->u_scale * pow((double)10.0,d_exp);
! 1071: } else { /* unit *tmp_str not found */
! 1072: /*printf("The unit: %s, not defined\n",tmp_str);*/
! 1073: err_code = 3;
! 1074: }
! 1075: } else {
! 1076: /*printf("<<%s>>", symb_str);*/
! 1077: err_code = 2;
! 1078: }
! 1079: } else {/* len == 1 */
! 1080: /*printf("The unit: %s, not defined\n",symb_str);*/
! 1081: err_code = 1;
! 1082: }
! 1083: }
! 1084: } else {
! 1085: err_code = 4;
! 1086: }
! 1087: return (err_code);
! 1088: }
! 1089:
! 1090: Unit_t *
! 1091: u_parse_unit(char *unit_str)
! 1092: {
! 1093: char *ch;
! 1094: char symb_str[QUARTER_K];
! 1095: int idx;
! 1096: double exp_sign;
! 1097: int s_result;
! 1098: int not_done;
! 1099: double s_number, offset;
! 1100: double tmp_scale, symb_exp, exp;
! 1101: Unit_t *cu_p;
! 1102:
! 1103: gUnitError=0;
! 1104: ch = unit_str;
! 1105: cu_p = (Unit_t *) capa_malloc(1, sizeof(Unit_t)); /* *** */
! 1106: cu_p->u_scale = 1.0;
! 1107: idx = 0; not_done = 1;
! 1108: exp_sign = 1.0; exp = 1;
! 1109: symb_str[0] = 0;
! 1110:
! 1111: while( isspace(*ch) ) { ch++; } /* trim leading white spaces */
! 1112: /* fprintf(stdout,"PARSE |%s|\n", unit_str); */
! 1113: while( not_done ) {
! 1114: if( isdigit(ch[idx]) || ch[idx] == '-' ) { /* rule 1: number */
! 1115: s_number = s_scan_number(ch,idx,&idx);
! 1116:
! 1117: tmp_scale = pow(s_number,exp_sign);
! 1118: /* printf("S=%g,Power(%g,%d)=%g\n",
! 1119: cu_p->u_scale, s_number,exp_sign, tmp_scale);
! 1120: */
! 1121: cu_p->u_scale = cu_p->u_scale * tmp_scale;
! 1122:
! 1123: /* printf("[Scale %g=%g^%g] ",tmp_scale,s_number,exp_sign); */
! 1124: while( isspace(ch[idx]) ) { idx++; }
! 1125: } else {
! 1126: if( isalpha(ch[idx]) ) { /* rule 2: unit_symbol ^ exp */
! 1127: symb_str[0] = 0;
! 1128: symb_exp = s_scan_symbol(ch,symb_str,idx,&idx);
! 1129: exp = (double)exp_sign * symb_exp;
! 1130: /* printf("[scanned %s ^ (%g * %g)] ", symb_str,symb_exp,exp_sign); fflush(stdout); */
! 1131: s_result = s_process_symb(symb_str,cu_p,exp);
! 1132: if( s_result > 0 ) {
! 1133: /* printf("Error processing symbol [%s]\n", symb_str); */
! 1134: gUnitError = 1;
! 1135: }
! 1136: while( isspace(ch[idx]) ) { idx++; }
! 1137: } else {
! 1138: if( ch[idx] == '*' || ch[idx] == '/' ) {
! 1139: if( ch[idx] == '/' ) { /* printf("[/] "); */ exp_sign = -1.0; }
! 1140: idx++;
! 1141: while( isspace(ch[idx]) ) { idx++; }
! 1142: } else {
! 1143: if( ch[idx] == '+' || ch[idx] == '-' ) {
! 1144: idx++;
! 1145: while( isspace(ch[idx]) ) { idx++; }
! 1146: offset = s_scan_number(ch,idx,&idx);
! 1147: /* printf("[Offset %g] ",offset); */
! 1148: } else {
! 1149: if( ch[idx] == 0 ) { /* end of input string */
! 1150: not_done = 0;
! 1151: /* printf("\n"); */
! 1152: } else {
! 1153: /* garbage in unit string */
! 1154: gUnitError = 1;
! 1155: not_done=0;
! 1156: }
! 1157: }
! 1158: }
! 1159: }
! 1160: }
! 1161: }
! 1162: simplify_unit(cu_p);
! 1163: return (cu_p);
! 1164:
! 1165: }
! 1166:
! 1167: void
! 1168: u_getunit(FILE *f)
! 1169: {
! 1170: register int unit_type;
! 1171: register int c;
! 1172: int power, result;
! 1173: char *name_p, *symbol_p, *comment_p, *unit_p;
! 1174:
! 1175: BaseUnitcnt = 0;
! 1176: free_utree(UnitTree_p);
! 1177: UnitTree_p = NULL;
! 1178: c_moveto_unit(f); /* move the file position to << */
! 1179: do {
! 1180: c_ignorewhite(f);
! 1181: c = getc(f); ungetc(c,f);
! 1182: if( c == '<' ) {
! 1183: unit_type = c_gettype(f);
! 1184: }
! 1185: if( c != EOF ) {
! 1186: switch(unit_type) {
! 1187: case U_BASE:
! 1188: name_p = c_getword(f); symbol_p = c_getword(f);
! 1189: comment_p = c_getcomment(f);
! 1190: /*
! 1191: printf("B Unit: N=%s,S=%s,C=%s\n",name_p,symbol_p,comment_p);
! 1192: */
! 1193: result = u_insert_baseunit(name_p,symbol_p,comment_p);
! 1194: if( result == 1 ) {
! 1195: printf("The entry %s is duplicated\n",symbol_p);
! 1196: }
! 1197: free(name_p); free(symbol_p); free(comment_p);
! 1198: break;
! 1199: case U_DERIVED:
! 1200: name_p = c_getword(f); symbol_p = c_getword(f);
! 1201: unit_p = c_getstring(f); comment_p = c_getcomment(f);
! 1202: /*
! 1203: printf("D Unit: N=%s,S=%s,C=%s,U=%s\n",
! 1204: name_p,symbol_p,comment_p,unit_p);
! 1205: */
! 1206: result = u_insert_derived(name_p,symbol_p,comment_p,unit_p);
! 1207: if( result == 1 ) {
! 1208: printf("The entry %s is duplicated\n",symbol_p);
! 1209: }
! 1210: /* preorder_utree(UnitTree_p); */
! 1211: free(name_p); free(symbol_p); free(comment_p); free(unit_p);
! 1212: break;
! 1213: case U_PREFIX:
! 1214: name_p = c_getword(f); symbol_p = c_getword(f);
! 1215: unit_p = c_getstring(f);
! 1216: /*
! 1217: printf("Prefix: N=%s,S=%s,U=%s\n",
! 1218: name_p,symbol_p,unit_p);
! 1219: */
! 1220: power = u_parsepower(unit_p);
! 1221: PrefixTbl[ (int)(*symbol_p) ] = power;
! 1222: /* printf(" P[%c]=%d\n",*symbol_p,power); */
! 1223: free(name_p); free(symbol_p); free(unit_p);
! 1224: break;
! 1225: case U_CONSTANT:
! 1226: symbol_p = c_getword(f); unit_p = c_getstring(f);
! 1227: comment_p = c_getcomment(f);
! 1228: /*
! 1229: printf("Const.: S=%s,C=%s,U=%s\n",
! 1230: symbol_p,comment_p,unit_p);
! 1231: */
! 1232: break;
! 1233: case U_UNKNOWN:
! 1234: /* printf("Unknown\n"); */
! 1235: break;
! 1236: }
! 1237: }
! 1238: } while ( c != EOF );
! 1239:
! 1240: }
! 1241:
! 1242: /* ----------------------------------------------------------------- */
! 1243: /* comparing unit symbol names should be case sensitive */
! 1244: int
! 1245: comp_unit_symb(a, b) char *a; char *b;
! 1246: {
! 1247: return strncmp(a,b,SYMBOL_MAXLEN);
! 1248: }
! 1249:
! 1250:
! 1251: Unit_t *
! 1252: u_splay (char *name, Unit_t *t)
! 1253: {
! 1254: Unit_t N;
! 1255: Unit_t *l, *r, *y;
! 1256:
! 1257: if (t == NULL) return t;
! 1258: N.u_left = (Unit_t *)NULL;
! 1259: N.u_right = (Unit_t *)NULL;
! 1260: l = r = &N;
! 1261:
! 1262: for (;;) {
! 1263: if ( comp_unit_symb(name,t->u_symbol) < 0 ) {
! 1264: if (t->u_left == NULL) break;
! 1265: if ( comp_unit_symb(name, (t->u_left)->u_symbol ) < 0 ) {
! 1266: y = t->u_left; t->u_left = y->u_right; y->u_right = t; t = y;
! 1267: if (t->u_left == NULL) break;
! 1268: }
! 1269: r->u_left = t; r = t; t = t->u_left;
! 1270: } else if ( comp_unit_symb(name,t->u_symbol) > 0 ) {
! 1271: if (t->u_right == NULL) break;
! 1272: if ( comp_unit_symb(name, (t->u_right)->u_symbol ) > 0 ) {
! 1273: y = t->u_right; t->u_right = y->u_left; y->u_left = t; t = y;
! 1274: if (t->u_right == NULL) break;
! 1275: }
! 1276: l->u_right = t; l = t; t = t->u_right;
! 1277: } else {
! 1278: break;
! 1279: }
! 1280: }
! 1281: l->u_right = t->u_left; r->u_left = t->u_right; t->u_left = N.u_right;
! 1282: t->u_right = N.u_left;
! 1283: return t;
! 1284: }
! 1285:
! 1286:
! 1287:
! 1288: /* returns: 0 correctly inserted */
! 1289: /* -1 error */
! 1290: /* 1 duplicate entry */
! 1291:
! 1292: int
! 1293: u_insert_baseunit(n_p,s_p,c_p) char *n_p, *s_p, *c_p;
! 1294: {
! 1295: Unit_t *new_p, *t;
! 1296: int len;
! 1297:
! 1298: new_p = (Unit_t *) capa_malloc(1, sizeof(Unit_t)); /* *** */
! 1299: if (new_p == NULL) {
! 1300: printf("Ran out of space\n");
! 1301: return(-1);
! 1302: }
! 1303: strcpy(new_p->u_symbol, s_p);
! 1304: strcpy(new_p->u_name, n_p);
! 1305: len = strlen(c_p);
! 1306: new_p->u_comment = (char *) capa_malloc((len+1), sizeof(char)); /* *** */
! 1307: strcpy(new_p->u_comment,c_p);
! 1308: BaseUnitcnt++;
! 1309: new_p->u_index = BaseUnitcnt;
! 1310: new_p->u_type = U_BASE;
! 1311: new_p->u_scale = 1.0;
! 1312: new_p->u_offset = 0.0;
! 1313: new_p->u_count = 0;
! 1314: new_p->u_list = NULL;
! 1315:
! 1316: if (UnitTree_p == NULL) { /* a new unit tree */
! 1317: UnitTree_p = new_p;
! 1318: return (0);
! 1319: }
! 1320: t = u_splay(s_p, UnitTree_p);
! 1321: if ( comp_unit_symb(s_p,t->u_symbol) < 0 ) {
! 1322: new_p->u_left = t->u_left; new_p->u_right = t;
! 1323: t->u_left = NULL;
! 1324: /* Splay_cnt++; */
! 1325: UnitTree_p = new_p;
! 1326: return (0);
! 1327: } else if ( comp_unit_symb(s_p,t->u_symbol) > 0 ) {
! 1328: new_p->u_right = t->u_right; new_p->u_left = t;
! 1329: t->u_right = NULL;
! 1330: /* Splay_cnt++; */
! 1331: UnitTree_p = new_p;
! 1332: return (0);
! 1333: } else { /* name and t->u_symbol is the same, which means found it */
! 1334: capa_mfree( (char *)new_p );
! 1335: UnitTree_p = t;
! 1336: return (1);
! 1337: }
! 1338: }
! 1339:
! 1340:
! 1341: int
! 1342: u_insert_derived(n_p,s_p,c_p,u_p)char *n_p, *s_p, *c_p, *u_p;
! 1343: {
! 1344: Unit_t *new_p, *t;
! 1345: int c_result, len;
! 1346:
! 1347: /* inorder_utree(UnitTree_p); */
! 1348: t = u_splay(s_p, UnitTree_p);
! 1349: UnitTree_p = t;
! 1350: c_result = comp_unit_symb(s_p,t->u_symbol);
! 1351: if ( c_result == 0 ) {
! 1352: UnitTree_p = t;
! 1353: return (1);
! 1354: }
! 1355:
! 1356: /* prepare a new Unit_t */
! 1357: new_p = u_parse_unit(u_p);
! 1358: strcpy(new_p->u_symbol,s_p);
! 1359: strcpy(new_p->u_name, n_p);
! 1360: new_p->u_type = U_DERIVED;
! 1361: len = strlen(c_p);
! 1362: new_p->u_comment = (char *) capa_malloc((len+1), sizeof(char)); /* *** */
! 1363: strcpy(new_p->u_comment,c_p);
! 1364:
! 1365: simplify_unit(new_p);
! 1366:
! 1367: /* print_unit_t(new_p); */
! 1368:
! 1369: if (c_result < 0 ) {
! 1370: new_p->u_left = t->u_left; new_p->u_right = t;
! 1371: t->u_left = NULL;
! 1372: } else { /* c_result > 0 */
! 1373: new_p->u_right = t->u_right; new_p->u_left = t;
! 1374: t->u_right = NULL;
! 1375: }
! 1376: UnitTree_p = new_p;
! 1377:
! 1378: return (0);
! 1379:
! 1380: }
! 1381:
! 1382: void
! 1383: freelist_unit_e(Unit_E *ue_p)
! 1384: {
! 1385: Unit_E *curr_p, *next_p;
! 1386:
! 1387: if( ue_p != NULL ) {
! 1388: next_p = ue_p->ue_nextp;
! 1389: curr_p = ue_p;
! 1390: if( next_p == NULL ) {
! 1391: capa_mfree((char *)curr_p);
! 1392: } else {
! 1393: for( curr_p = ue_p; next_p; curr_p = next_p, next_p = next_p->ue_nextp) {
! 1394: capa_mfree((char *)curr_p);
! 1395: }
! 1396: capa_mfree((char *)curr_p);
! 1397: }
! 1398: }
! 1399: }
! 1400: void
! 1401: simplify_unit(u_p) Unit_t *u_p;
! 1402: {
! 1403: Unit_E *eu_p, *prev_p;
! 1404: int ii, idx;
! 1405:
! 1406: /* walk through u_list and replace those u_index = -1 with */
! 1407: /* a linked list of basic unit. */
! 1408: /* u_msort_main() the whole u_list */
! 1409: /* combine those units with same u_index */
! 1410: for(ii=0;ii<BaseUnitcnt;ii++) {
! 1411: CScale[ii] = 0.0;
! 1412: CExp[ii] = 0.0;
! 1413: }
! 1414: if( u_p->u_count > 0 ) {
! 1415:
! 1416: for(eu_p=u_p->u_list; eu_p; eu_p = eu_p->ue_nextp) {
! 1417: idx = eu_p->ue_index;
! 1418: if( CScale[idx] == 0.0 ) {
! 1419: CScale[idx] = 1.0;
! 1420: strcpy(CSymb[idx],eu_p->ue_symbol);
! 1421: }
! 1422: CScale[idx] = CScale[idx] * eu_p->ue_scale;
! 1423: CExp[idx] = CExp[idx] + eu_p->ue_exp;
! 1424: }
! 1425: /*
! 1426: for(ii=0;ii<BaseUnitcnt;ii++) {
! 1427: if( CScale[ii] != 0.0 ) {
! 1428: printf("(%d)%s,S=%g,E=%g\n",ii,CSymb[ii],CScale[ii], CExp[ii]);
! 1429: }
! 1430: }
! 1431: */
! 1432: freelist_unit_e(u_p->u_list);
! 1433: prev_p = u_p->u_list = NULL;
! 1434: u_p->u_count = 0;
! 1435: for(ii=0;ii<BaseUnitcnt;ii++) {
! 1436: if( CScale[ii] != 0.0 && CExp[ii] != 0) {
! 1437: eu_p = (Unit_E *)capa_malloc(1,sizeof(Unit_E)); /* ***************** */
! 1438: eu_p->ue_scale = 1.0;
! 1439: eu_p->ue_exp = CExp[ii];
! 1440: eu_p->ue_index = ii;
! 1441: strcpy(eu_p->ue_symbol,CSymb[ii]);
! 1442: if( prev_p == NULL) {
! 1443: u_p->u_list = prev_p = eu_p;
! 1444: } else {
! 1445: prev_p->ue_nextp = eu_p;
! 1446: prev_p = eu_p;
! 1447: }
! 1448: u_p->u_count++;
! 1449: }
! 1450: }
! 1451:
! 1452:
! 1453: }
! 1454:
! 1455: }
! 1456:
! 1457: /* before comparing two units, make sure they are of basic form */
! 1458: /* compares if two units are equal */
! 1459: /* equality returns 1 */
! 1460:
! 1461: int is_units_equal(Unit_t *u1_p, Unit_t *u2_p)
! 1462: {
! 1463: int result=1;
! 1464: Unit_E *a_p, *b_p;
! 1465:
! 1466: if( (u1_p->u_count == u2_p->u_count) &&
! 1467: (u1_p->u_scale == u2_p->u_scale) ) {
! 1468: for(a_p=u1_p->u_list, b_p=u2_p->u_list;
! 1469: a_p; a_p=a_p->ue_nextp, b_p=b_p->ue_nextp) {
! 1470: if(a_p->ue_index != b_p->ue_index ||
! 1471: a_p->ue_scale != b_p->ue_scale ||
! 1472: a_p->ue_exp != b_p->ue_exp ) {
! 1473: result=0;
! 1474: break;
! 1475: }
! 1476: }
! 1477: } else {
! 1478: result=0;
! 1479: }
! 1480: return (result);
! 1481: }
! 1482: /* input : both are the simplest units */
! 1483: /* result: 0.0 means they are not of euquvalent units */
! 1484: /* the ratio of u1 / u2 */
! 1485: double units_ratio(Unit_t *u1_p, Unit_t *u2_p)
! 1486: {
! 1487: double ratio=1.0;
! 1488: Unit_E *a_p, *b_p;
! 1489:
! 1490: if( (u1_p->u_count == u2_p->u_count) ) {
! 1491: for(a_p=u1_p->u_list, b_p=u2_p->u_list;
! 1492: a_p; a_p=a_p->ue_nextp, b_p=b_p->ue_nextp) {
! 1493: if(a_p->ue_index != b_p->ue_index ||
! 1494: a_p->ue_scale != b_p->ue_scale ||
! 1495: a_p->ue_exp != b_p->ue_exp ) {
! 1496: ratio=0.0;
! 1497: break;
! 1498: }
! 1499: }
! 1500: } else {
! 1501: ratio=0.0;
! 1502: }
! 1503: if( (ratio != 0.0) && (u2_p->u_scale != 0.0 ) ) {
! 1504: ratio = u1_p->u_scale / u2_p->u_scale;
! 1505: }
! 1506: return (ratio);
! 1507: }
! 1508:
! 1509: /* ------------- The Grammar of Units Parser --------------------
! 1510:
! 1511: scan_unit_expr() --> scan_basic_block()
! 1512: --> scan_basic_block() '+' scan_basic_block()
! 1513: --> scan_basic_block() '-' scan_basic_block()
! 1514:
! 1515: scan_num_expr() --> scan_num_block()
! 1516: --> scan_num_block() '+' scan_num_block()
! 1517: --> scan_num_block() '-' scan_num_block()
! 1518:
! 1519: scan_basic_block()--> scan_basic_term()
! 1520: --> scan_basic_term() '*' scan_basic_term()
! 1521: --> scan_basic_term() ' ' scan_basic_term()
! 1522: --> scan_basic_term() '/' scan_basic_term()
! 1523:
! 1524: scan_num_block() --> scan_num_term()
! 1525: --> scan_num_term() '*' scan_num_term()
! 1526: --> scan_num_term() ' ' scan_num_term()
! 1527: --> scan_num_term() '/' scan_num_term()
! 1528:
! 1529:
! 1530: scan_basic_term() --> scan_unit_item()
! 1531: --> scan_num_item()
! 1532: --> '(' scan_basic_block() ')'
! 1533: --> '{' scan_basic_block() '}'
! 1534:
! 1535: scan_num_term() --> scan_num_item()<sp>*
! 1536: --> '-' scan_num_item()<sp>*
! 1537: --> '(' scan_num_expr() ')'
! 1538: --> '{' scan_num_expr() '}'
! 1539:
! 1540: scan_unit_item() --> UNIT<sp>*
! 1541: --> UNIT<sp>* '^' <sp>* scan_num_term()
! 1542:
! 1543: scan_num_item() --> FLOAT<sp>*
! 1544: --> FLOAT<sp>* '^' <sp>* scan_num_term()
! 1545:
! 1546: scan_FLOAT() --> [0-9]+([eE][+-]?[0-9]+)*
! 1547:
! 1548: p_new_unit() --> [a-Z]+[a-Z0-9_]*
! 1549:
! 1550: -----------------------------------------
! 1551: U.expr := B.block
! 1552: | B.block '+' B.block
! 1553: | B.block '-' B.block
! 1554:
! 1555: N.expr := N.block
! 1556: | N.block '+' N.block
! 1557: | N.block '-' N.block
! 1558:
! 1559: To allow for operations like (J/N)^2 or {N/m}^2 (N/J)^3
! 1560:
! 1561:
! 1562: B.block := B.term
! 1563: | B.term ' ' B.term
! 1564: | B.term '*' B.term
! 1565: | B.term '/' B.term
! 1566:
! 1567: N.block := N.term
! 1568: | N.term ' ' N.term
! 1569: | N.term '*' N.term
! 1570: | N.term '/' N.term
! 1571:
! 1572: B.term := U.item
! 1573: | N.item
! 1574: | '(' B.block ')'
! 1575: | '{' B.block '}'
! 1576:
! 1577: | '(' B.block ')' ^ N.term
! 1578: | '{' B.block '}' ^ N.term
! 1579:
! 1580: N.term := N.item
! 1581: | '-' N.item
! 1582: | '(' N.expr ')'
! 1583: | '{' N.expr '}'
! 1584:
! 1585: U.item := UNIT
! 1586: | UNIT '^' N.term
! 1587:
! 1588: N.item := FLOAT
! 1589: | FLOAT '^' N.term
! 1590:
! 1591: UNIT := [a-Z]+[a-Z0-9_]*
! 1592:
! 1593: FLOAT := [0-9]+([eE][+-]?[0-9]+)*
! 1594:
! 1595: ------------------------------------------------------------------- */
! 1596:
! 1597: Unit_t *
! 1598: p_new_op(Unit_t *left_p, int op, Unit_t *right_p)
! 1599: {
! 1600: Unit_t *new_p;
! 1601:
! 1602: new_p = (Unit_t *) capa_malloc(1, sizeof(Unit_t));
! 1603: if (new_p == NULL) {
! 1604: printf("Ran out of space\n");
! 1605: return(NULL);
! 1606: }
! 1607: new_p->u_left = left_p;
! 1608: new_p->u_right = right_p;
! 1609: new_p->u_scale = 0.0;
! 1610: new_p->u_type = op;
! 1611: new_p->u_offset = 0.0;
! 1612: new_p->u_count = 0;
! 1613: new_p->u_list = NULL;
! 1614:
! 1615: return (new_p);
! 1616: }
! 1617:
! 1618: Unit_t *
! 1619: p_new_num(Unit_t *left_p, double num, Unit_t *right_p)
! 1620: {
! 1621: Unit_t *new_p;
! 1622:
! 1623: new_p = (Unit_t *) capa_malloc(1, sizeof(Unit_t));
! 1624: if (new_p == NULL) {
! 1625: printf("Ran out of space\n");
! 1626: return(NULL);
! 1627: }
! 1628:
! 1629: new_p->u_left = left_p;
! 1630: new_p->u_right = right_p;
! 1631: new_p->u_scale = num;
! 1632: new_p->u_type = U_CONSTANT;
! 1633: new_p->u_offset = 0.0;
! 1634: new_p->u_count = 0;
! 1635: new_p->u_list = NULL;
! 1636:
! 1637: return (new_p);
! 1638: }
! 1639:
! 1640: Unit_t *
! 1641: p_new_unit(Unit_t *left_p, Unit_t *right_p)
! 1642: {
! 1643: char symb_str[ANSWER_STRING_LENG];
! 1644: int ii=0;
! 1645: int len;
! 1646: Unit_t *au_p, *cu_p;
! 1647: int c_result;
! 1648: char tmp_str[ANSWER_STRING_LENG];
! 1649: int err_code = 0;
! 1650: double d_exp;
! 1651:
! 1652: symb_str[ii]=0;
! 1653: while( isspace(Sbuf[Sidx]) ) { Sidx++; }
! 1654: while( isalnum(Sbuf[Sidx]) || Sbuf[Sidx] == '_' ) {
! 1655: symb_str[ii++] = Sbuf[Sidx];
! 1656: Sidx++;
! 1657: }
! 1658: symb_str[ii]=0;
! 1659: /* printf("<U %s>", symb_str); */
! 1660: cu_p = (Unit_t *) capa_malloc(1, sizeof(Unit_t));
! 1661: strcpy(cu_p->u_symbol,symb_str);
! 1662: cu_p->u_left = left_p;
! 1663: cu_p->u_right = right_p;
! 1664: cu_p->u_scale = 1.0;
! 1665: cu_p->u_type = U_DERIVED;
! 1666: cu_p->u_offset = 0.0;
! 1667: cu_p->u_count = 0;
! 1668: cu_p->u_list = NULL;
! 1669:
! 1670: len = strlen(symb_str);
! 1671: if( len > 0 ) {
! 1672: au_p = u_find_symb(symb_str, UnitTree_p, &c_result);
! 1673: if( c_result == 1 ) { /* if found, copy the definition over */
! 1674: u_copy_unit(cu_p, au_p, 1);
! 1675: } else {
! 1676: if( len > 1 ) {
! 1677: if( PrefixTbl[ (int)symb_str[0] ] != 0 ) { /* prefix is defined */
! 1678: for(ii=1;ii<len;ii++) {
! 1679: tmp_str[ii-1] = symb_str[ii];
! 1680: }
! 1681: tmp_str[len-1]=0;
! 1682: au_p = u_find_symb(tmp_str, UnitTree_p, &c_result);
! 1683: if( c_result == 1 ) {
! 1684: /* printf("[%s] ", tmp_str); */
! 1685: u_copy_unit(cu_p, au_p, 1);
! 1686: d_exp = (double)PrefixTbl[ (int)symb_str[0] ];
! 1687: cu_p->u_scale = cu_p->u_scale * pow((double)10.0,d_exp);
! 1688: } else { /* unit *tmp_str not found */
! 1689: /* printf(" not found\n"); */
! 1690: err_code = 3;
! 1691: }
! 1692: } else {
! 1693: /* printf("<<%s>>", symb_str); */
! 1694: err_code = 2;
! 1695: }
! 1696: } else {/* len == 1 */
! 1697: /* printf(" not found\n"); */
! 1698: err_code = 1;
! 1699: }
! 1700: }
! 1701: } else {
! 1702: err_code = 4;
! 1703: }
! 1704:
! 1705: return (cu_p);
! 1706: }
! 1707:
! 1708: int s_peeknext_op()
! 1709: {
! 1710: char *ch;
! 1711: int sp=0;
! 1712:
! 1713: ch = (char *)&Sbuf[Sidx];
! 1714: while( isspace(*ch) ) { ch++; sp=1; }
! 1715: if( (*ch == '*') || (*ch == '/') || (*ch == '+') || (*ch == '-') || (*ch == '^')) {
! 1716: return (*ch);
! 1717: }
! 1718: /* what if space is the last thing on the line?*/
! 1719: if( sp && (*ch != '\0')) return '*';
! 1720: return (*ch);
! 1721: }
! 1722:
! 1723: int s_getnext_op()
! 1724: {
! 1725: char *ch;
! 1726: int inc = 0, sp=0;
! 1727:
! 1728:
! 1729: /* printf("\n((op"); print_remains(); printf("\n"); */
! 1730: ch = (char *)&Sbuf[Sidx];
! 1731: while( isspace(*ch) ) { ch++; inc++; sp=1; }
! 1732: Sidx = Sidx + inc;
! 1733: if( (*ch == '*') || (*ch == '/') || (*ch == '+') || (*ch == '-') || (*ch == '^') ) {
! 1734: Sidx++;
! 1735: /* print_remains(); printf(" op))"); printf("\n"); */
! 1736: return (*ch);
! 1737: }
! 1738: /* print_remains(); printf(" op))"); printf("\n"); */
! 1739: /* what if space is the last thing on the line?*/
! 1740: if( sp && (*ch != '\0')) return '*';
! 1741: return (*ch);
! 1742: }
! 1743:
! 1744: int
! 1745: s_getnext()
! 1746: {
! 1747: char ch;
! 1748:
! 1749: ch = Sbuf[Sidx];
! 1750: Sidx++;
! 1751: return (ch);
! 1752: }
! 1753:
! 1754: int
! 1755: s_peeknext()
! 1756: {
! 1757: char ch;
! 1758:
! 1759: ch = Sbuf[Sidx];
! 1760: return (ch);
! 1761: }
! 1762:
! 1763: int
! 1764: s_peeknextNW() /* peek into the next non-whitespaces character */
! 1765: {
! 1766: char *ch;
! 1767:
! 1768: ch = (char *)&Sbuf[Sidx];
! 1769: while( isspace(*ch) ) { ch++; }
! 1770: return (*ch);
! 1771: }
! 1772:
! 1773: int
! 1774: s_getnextNW() /* get the next non-whitespaces character */
! 1775: {
! 1776: char *ch;
! 1777:
! 1778: ch = (char *)&Sbuf[Sidx]; Sidx++;
! 1779: while( isspace(*ch) ) { ch++; Sidx++; }
! 1780: return (*ch);
! 1781: }
! 1782: /* peek into the next non-whitespaces character
! 1783: which should be either a multiply or division */
! 1784: int
! 1785: s_peekMDWS()
! 1786: {
! 1787: char *ch;
! 1788: int sp=0;
! 1789:
! 1790: ch = (char *)&Sbuf[Sidx];
! 1791: while( isspace(*ch) ) { ch++; sp=1;}
! 1792: if( (*ch == '*') || (*ch == '/') ) {
! 1793: return (*ch);
! 1794: }
! 1795: if( sp ) return ' ';
! 1796: ch = (char *)&Sbuf[Sidx];
! 1797: while( isspace(*ch) ) { ch++; }
! 1798: return (*ch);
! 1799: }
! 1800:
! 1801: int
! 1802: s_getnextMDWS()
! 1803: {
! 1804: char *ch;
! 1805: int inc=0, sp=0;
! 1806:
! 1807: ch = (char *)&Sbuf[Sidx]; Sidx++;
! 1808: while( isspace(*ch) ) { ch++; inc++; sp=1; }
! 1809: Sidx += inc;
! 1810: if( (*ch == '*') || (*ch == '/') ) {
! 1811: return (*ch);
! 1812: }
! 1813: if( sp ) return ' ';
! 1814: return (*ch);
! 1815: }
! 1816:
! 1817: double
! 1818: scan_FLOAT()
! 1819: {
! 1820: double num;
! 1821: int ii=0, len;
! 1822: char num_str[QUARTER_K];
! 1823:
! 1824: num_str[ii]=0;
! 1825: while( isspace(Sbuf[Sidx]) ) { Sidx++; }
! 1826: if( Sbuf[Sidx] == '-' ) {
! 1827: num_str[ii++] = Sbuf[Sidx++];
! 1828: }
! 1829: while( isdigit(Sbuf[Sidx]) || Sbuf[Sidx] == '.' ) {
! 1830: num_str[ii++] = Sbuf[Sidx++];
! 1831: }
! 1832: if( Sbuf[Sidx] == 'E' || Sbuf[Sidx] == 'e' ) {
! 1833: if( Sbuf[Sidx+1] == '-' || isdigit(Sbuf[Sidx+1]) ) {
! 1834: num_str[ii++] = Sbuf[Sidx++];
! 1835: num_str[ii++] = Sbuf[Sidx++];
! 1836: while( isdigit(Sbuf[Sidx]) ) {
! 1837: num_str[ii++] = Sbuf[Sidx++];
! 1838: }
! 1839: }
! 1840: }
! 1841: num_str[ii] = 0; /* terminate the str */
! 1842: len = strlen(num_str);
! 1843: if(len > 0 ) {
! 1844: sscanf(num_str,"%lg", &num);
! 1845: /* printf("<N %s %g>",num_str,num); fflush(stdout); print_remains(); */
! 1846: } else {
! 1847: num = 1.0;
! 1848: }
! 1849: return (num);
! 1850: }
! 1851: /* -----------------------------------------------
! 1852: N.item := FLOAT
! 1853: | FLOAT '^' N.term
! 1854: ----------------------------------------------- */
! 1855: Unit_t *
! 1856: scan_num_item()
! 1857: {
! 1858: Unit_t *node_p, *exp_p;
! 1859: double num_const;
! 1860: char ch;
! 1861:
! 1862: num_const = scan_FLOAT();
! 1863: node_p = p_new_num(NULL, num_const, NULL);
! 1864: ch = s_peeknext_op();
! 1865: if( ch == '^' ) {
! 1866: ch = s_getnext_op();
! 1867:
! 1868: exp_p = scan_num_term();
! 1869: num_const = node_p->u_scale;
! 1870: if( node_p->u_scale > 0.0 ) {
! 1871: num_const = pow(node_p->u_scale,exp_p->u_scale);
! 1872: }
! 1873: node_p->u_scale = num_const;
! 1874: capa_mfree((char *)exp_p);
! 1875: }
! 1876: return node_p;
! 1877: }
! 1878:
! 1879: /* -----------------------------------------------
! 1880: U.item := UNIT
! 1881: | UNIT '^' N.term
! 1882: ----------------------------------------------- */
! 1883:
! 1884: Unit_t *
! 1885: scan_unit_item()
! 1886: {
! 1887: Unit_t *node_p, *exp_p;
! 1888: char ch;
! 1889: double num_const;
! 1890: Unit_E *oe_p;
! 1891:
! 1892: node_p = p_new_unit(NULL,NULL);
! 1893: ch = s_peeknext_op();
! 1894: if( ch == '^' ) {
! 1895: ch = s_getnext_op();
! 1896: exp_p = scan_num_term();
! 1897: num_const = exp_p->u_scale;
! 1898: if( node_p->u_count > 0 ) {
! 1899: oe_p = node_p->u_list;
! 1900: for(oe_p = node_p->u_list; oe_p; oe_p = oe_p->ue_nextp ) {
! 1901: oe_p->ue_exp = oe_p->ue_exp * num_const;
! 1902: }
! 1903: }
! 1904: num_const = node_p->u_scale;
! 1905: if( node_p->u_scale > 0.0 ) {
! 1906: num_const = pow(node_p->u_scale,exp_p->u_scale);
! 1907: }
! 1908: node_p->u_scale = num_const;
! 1909: capa_mfree((char *)exp_p);
! 1910: }
! 1911: return node_p;
! 1912: }
! 1913:
! 1914: void distribute_exp(Unit_t* node_p,Unit_t* exp_p)
! 1915: {
! 1916: Unit_E* oe_p;
! 1917: double num_const;
! 1918: num_const = exp_p->u_scale; /* should we check if num_const too large or small ? */
! 1919: if( node_p->u_count > 0 ) {
! 1920: oe_p = node_p->u_list;
! 1921: for(oe_p = node_p->u_list; oe_p; oe_p = oe_p->ue_nextp ) {
! 1922: oe_p->ue_exp = oe_p->ue_exp * num_const;
! 1923: }
! 1924: }
! 1925: num_const = node_p->u_scale;
! 1926: if( node_p->u_scale > 0.0 ) { /* what if u_scale <= 0.0 ? */
! 1927: num_const = pow(node_p->u_scale,exp_p->u_scale);
! 1928: }
! 1929: node_p->u_scale = num_const;
! 1930: if (node_p->u_left) distribute_exp(node_p->u_left,exp_p);
! 1931: if (node_p->u_right) distribute_exp(node_p->u_right,exp_p);
! 1932: }
! 1933:
! 1934: /* ---------------------------------------------------------------
! 1935: B.term := U.item
! 1936: | N.item
! 1937: | '(' B.block ')'
! 1938: | '{' B.block '}'
! 1939:
! 1940: | '(' B.block ')' '^' N.term <== July 6 1998
! 1941: | '{' B.block '}' '^' N.term
! 1942:
! 1943: --------------------------------------------------------------- */
! 1944: Unit_t *
! 1945: scan_basic_term()
! 1946: {
! 1947: Unit_t *node_p, *exp_p;
! 1948: int ch, nch;
! 1949:
! 1950: ch = s_peeknextNW();
! 1951: if( ch == '(' || ch == '{' ) {
! 1952: ch = s_getnextNW(); /* get rid of '(' or '{' */
! 1953: node_p = scan_basic_block();
! 1954: nch = s_peeknextNW();
! 1955: if( nch == ')' || nch == '}' ) { /* should be either ')' or '}' */
! 1956: if( ((ch == '(' ) && (nch == ')' )) ||
! 1957: ((ch == '{' ) && (nch == '}' )) ) { /* matching left paren with right paren */
! 1958:
! 1959:
! 1960: } else {
! 1961: /* printf(" WARN: %c matched by %c\n", ch, nch); */
! 1962: }
! 1963: nch = s_getnextNW();
! 1964: /* ====== Added Jul 6, 1998 ====> */
! 1965: ch = s_peeknext_op();
! 1966: if( ch == '^' ) {
! 1967: ch = s_getnext_op(); /* get rid of '^' char */
! 1968: exp_p = scan_num_term();
! 1969: distribute_exp(node_p,exp_p);
! 1970: capa_mfree((char *)exp_p);
! 1971: }
! 1972: /* <== added Jul 6, 1998 == */
! 1973: } else {
! 1974: /* printf(" WARN: %c is not matched by %c\n", ch, nch); */
! 1975: }
! 1976: } else if( ch >= '0' && ch <= '9' ) {
! 1977: node_p = scan_num_item();
! 1978: } else { /* assume a unit symbol */
! 1979: /* printf("<B.term>"); print_remains(); */
! 1980: node_p = scan_unit_item();
! 1981: /* print_remains(); */
! 1982: }
! 1983: return node_p;
! 1984: }
! 1985: /* --------------------------------------------------
! 1986: N.term := N.item
! 1987: | '-' N.item
! 1988: | '(' N.expr ')'
! 1989: | '{' N.expr '}'
! 1990: -------------------------------------------------- */
! 1991: Unit_t *
! 1992: scan_num_term()
! 1993: {
! 1994: Unit_t *node_p;
! 1995: char ch, nch;
! 1996:
! 1997: ch = s_peeknextNW();
! 1998: if( ch == '(' || ch == '{' ) {
! 1999: ch = s_getnextNW();
! 2000: node_p = scan_num_expr();
! 2001: nch = s_peeknextNW();
! 2002: if( nch == ')' || nch == '}' ) { /* should be either ')' or '}' */
! 2003: if( ((ch == '(' ) && (nch == ')' )) ||
! 2004: ((ch == '{' ) && (nch == '}' )) ) {
! 2005:
! 2006: } else {
! 2007: /* printf(" WARN: %c matched by %c\n", ch, nch); */
! 2008: }
! 2009: nch = s_getnextNW();
! 2010: } else {
! 2011: /* printf(" WARN: %c is not matched by %c\n", ch, ch); */
! 2012: }
! 2013: } else if( ch == '-' ) {
! 2014: ch = s_getnextNW();
! 2015: node_p = scan_num_item();
! 2016: node_p->u_scale = (-1)*node_p->u_scale;
! 2017: } else {
! 2018: if( isdigit(ch) ) {
! 2019: node_p = scan_num_item();
! 2020: } else { /* something other than a number */
! 2021: /*
! 2022: printf(" ERROR: expect a number: ");
! 2023: print_remains();
! 2024: */
! 2025: node_p = p_new_num(NULL, 0.0, NULL); /* make the unknown item */
! 2026: }
! 2027: }
! 2028: return node_p;
! 2029: }
! 2030:
! 2031: /* --------------------------------------------------
! 2032: B.block := B.term
! 2033: | B.term ' ' B.term
! 2034: | B.term '*' B.term
! 2035: | B.term '/' B.term
! 2036: -------------------------------------------------- */
! 2037: Unit_t *
! 2038: scan_basic_block()
! 2039: {
! 2040: Unit_t *node_p;
! 2041: char ch;
! 2042: int op;
! 2043:
! 2044: /* printf("<B.block>(before B.term)"); print_remains(); */
! 2045: node_p = scan_basic_term();
! 2046: ch = s_peeknext_op();
! 2047: while ( ch == '*' || ch == '/' ) {
! 2048: op = ( ch == '/' ? U_OP_DIVIDE : U_OP_TIMES);
! 2049: ch = s_getnext_op();
! 2050: /* printf("<B.block>(/ *)"); print_remains(); */
! 2051: node_p = p_new_op(node_p,op,scan_basic_term());
! 2052: ch = s_peeknext_op();
! 2053: }
! 2054: return node_p;
! 2055: }
! 2056: /* --------------------------------------------------
! 2057: N.block := N.term
! 2058: | N.term ' ' N.term
! 2059: | N.term '*' N.term
! 2060: | N.term '/' N.term
! 2061: -------------------------------------------------- */
! 2062: Unit_t *
! 2063: scan_num_block()
! 2064: {
! 2065: Unit_t *node_p, *opand_p;
! 2066: char ch;
! 2067: double result;
! 2068:
! 2069: node_p = scan_num_term();
! 2070: ch = s_peeknext_op();
! 2071: while ( ch == '*' || ch == '/' ) {
! 2072: s_getnext_op();
! 2073: opand_p = scan_num_term();
! 2074: if( ch == '*' ) {
! 2075: result = node_p->u_scale * opand_p->u_scale;
! 2076: } else {
! 2077: result = node_p->u_scale / opand_p->u_scale;
! 2078: }
! 2079: node_p->u_scale = result;
! 2080: capa_mfree((char *)opand_p);
! 2081: ch = s_peeknext_op();
! 2082: }
! 2083: return node_p;
! 2084: }
! 2085:
! 2086: /* ---------------------------------------
! 2087: U.expr := B.block
! 2088: | B.block '+' B.block
! 2089: | B.block '-' B.block
! 2090: --------------------------------------- */
! 2091: Unit_t *
! 2092: scan_unit_expr()
! 2093: {
! 2094: Unit_t *node_p;
! 2095: char ch;
! 2096: int op;
! 2097:
! 2098: /* printf("<U.expr>"); print_remains(); */
! 2099: node_p = scan_basic_block();
! 2100: ch = s_peeknext_op();
! 2101: while ( ch == '+' || ch == '-' ) {
! 2102: op = ( ch == '+' ? U_OP_PLUS : U_OP_MINUS);
! 2103: ch = s_getnext_op();
! 2104: /* printf("<U.expr>(+-)"); print_remains(); */
! 2105: node_p = p_new_op(node_p,op,scan_basic_block());
! 2106: ch = s_peeknext_op();
! 2107: }
! 2108: return node_p;
! 2109: }
! 2110: /* -----------------------------------------
! 2111: N.expr := N.block
! 2112: | N.block '+' N.block
! 2113: | N.block '-' N.block
! 2114: ----------------------------------------- */
! 2115: Unit_t *
! 2116: scan_num_expr()
! 2117: {
! 2118: Unit_t *node_p, *opand_p;
! 2119: char ch;
! 2120: double result;
! 2121:
! 2122: node_p = scan_num_block();
! 2123: ch = s_peeknext_op();
! 2124: while ( ch == '+' || ch == '-' ) {
! 2125: ch = s_getnext_op();
! 2126: opand_p = scan_num_block();
! 2127: if( ch == '+' ) {
! 2128: result = node_p->u_scale + opand_p->u_scale;
! 2129: } else {
! 2130: result = node_p->u_scale - opand_p->u_scale;
! 2131: }
! 2132: node_p->u_scale = result;
! 2133: capa_mfree((char *)opand_p);
! 2134: ch = s_peeknext_op();
! 2135: }
! 2136: return node_p;
! 2137: }
! 2138:
! 2139: /* ----------------------------------------------------------------------- */
! 2140: /* <-- This is the major entry point to parse an units expression ------> */
! 2141: Unit_t *
! 2142: parse_unit_expr(char *symb_str)
! 2143: {
! 2144: Unit_t *root_p;
! 2145: int len;
! 2146:
! 2147: len = strlen(symb_str);
! 2148: strcpy(Sbuf,symb_str); /* copy it into the global Sbuf */
! 2149: Sidx=0;
! 2150: root_p = scan_unit_expr();
! 2151: if(Sidx < len-1 ) {
! 2152: /* printf(" WARN: NOT PARSED:"); print_remains(); */
! 2153: }
! 2154: return (root_p);
! 2155:
! 2156: }
! 2157:
! 2158: void
! 2159: print_remains()
! 2160: {
! 2161: int len, ii;
! 2162:
! 2163: len = strlen(Sbuf);
! 2164: printf("[[");
! 2165: for(ii=Sidx;ii<len;ii++) {
! 2166: printf("%c",Sbuf[ii]);
! 2167: }
! 2168: printf("]]");
! 2169:
! 2170: }
! 2171:
! 2172:
! 2173:
! 2174: /* =================================================================== */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>