Annotation of capa/capa51/pProj/capaFormula.y, revision 1.9

1.3       albertel    1: /* formula parser
                      2:    Copyright (C) 1992-2000 Michigan State University
                      3: 
                      4:    The CAPA system is free software; you can redistribute it and/or
1.6       albertel    5:    modify it under the terms of the GNU General Public License as
1.3       albertel    6:    published by the Free Software Foundation; either version 2 of the
                      7:    License, or (at your option) any later version.
                      8: 
                      9:    The CAPA system is distributed in the hope that it will be useful,
                     10:    but WITHOUT ANY WARRANTY; without even the implied warranty of
                     11:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1.6       albertel   12:    General Public License for more details.
1.3       albertel   13: 
1.6       albertel   14:    You should have received a copy of the GNU General Public
1.3       albertel   15:    License along with the CAPA system; see the file COPYING.  If not,
                     16:    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
1.5       albertel   17:    Boston, MA 02111-1307, USA.
                     18: 
                     19:    As a special exception, you have permission to link this program
                     20:    with the TtH/TtM library and distribute executables, as long as you
                     21:    follow the requirements of the GNU GPL in regard to all of the
                     22:    software in the executable aside from TtH/TtM.
                     23: */
1.1       albertel   24: 
                     25: /* ====================================================== */
                     26: /*      capaFormula.y  created by Isaac Tsai @ Feb 1999   */
                     27: /*  TODO: checking user inputs   2/27/99      IT          */
                     28: /* ====================================================== */
                     29: %{
                     30: #include <stdio.h>
                     31: #include <ctype.h>
                     32: #include <string.h>
                     33: #include <math.h>
                     34: #include "capaParser.h"   /* _symbol structure def */
                     35: #include "capaCommon.h"
                     36: #include "capaFunction.h"
1.2       albertel   37: #ifdef  YYSTYPE
                     38: #undef  YYSTYPE
                     39: #endif
                     40: #define YYSTYPE  Symbol_p
1.1       albertel   41: #include "capaToken.h"
                     42: 
                     43: #ifdef __hpux
                     44: #include <stdlib.h>
                     45: #include <alloca.h>
                     46: #endif
                     47: 
                     48: #ifdef   FML_DBUG
                     49: #define  FMLDBUG_PR1(xx)        { printf(xx);    fflush(stdout); }
                     50: #define  FMLDBUG_PR2(xx,yy)     { printf(xx,yy); fflush(stdout); }
                     51: #define  FMLDBUG_PR3(xx,yy,zz)  { printf(xx,yy,zz); fflush(stdout); }
                     52: #else
                     53: #define  FMLDBUG_PR1(xx)        { }
                     54: #define  FMLDBUG_PR2(xx,yy)     { }
                     55: #define  FMLDBUG_PR3(xx,yy,zz)  { }
                     56: #endif
                     57: 
                     58: #define ADD_op          1
                     59: #define SUB_op          2
                     60: #define MUL_op          3
                     61: #define DIV_op          4
                     62: #define IDIV_op         5
                     63: #define NOT_DEFINED_op  9
                     64: 
                     65: 
                     66: /* =============================================================== */
                     67: 
                     68: extern      int         Func_idx;
                     69: extern      Symbol      FuncStack[MAX_FUNC_NEST];
1.2       albertel   70: void   fml_error(char *msg);
1.1       albertel   71: double      FormulaVal;
                     72: int         FormulaParseOK=1;
                     73: 
                     74: %}
                     75: 
                     76: 
                     77: %token    F_NUMBER    V_ID      F_ID     EoI      F_ERROR 
                     78: %left     F_PLUS      F_MINUS   
                     79: %left     F_MULT      F_DIV     F_MOD
1.9     ! albertel   80: %token    F_POW
        !            81: %token    F_LPAR    F_RPAR   F_COMMA 
1.1       albertel   82: 
                     83: 
                     84: %start    f_expr
                     85: 
                     86: 
                     87: %%
                     88: 
                     89: f_expr       : block                             { switch($1->s_type) {
                     90:                                                       case I_VAR:
                     91:                                                       case I_CONSTANT: FormulaVal = (double)($1->s_int);
                     92:                                                           break;
                     93:                                                       case R_VAR: 
                     94:                                                       case R_CONSTANT: FormulaVal = $1->s_real;
                     95:                                                           break;
                     96:                                                       case S_VAR:
                     97:                                                       case S_CONSTANT: FormulaParseOK = 0;
                     98:                                                           break;
                     99:                                                       default:         FormulaParseOK = 0;
                    100:                                                           break;
                    101:                                                     }
                    102:                                                     capa_mfree((char *)$1);
                    103:                                                     FMLDBUG_PR1("[f_expr <= block ]\n");
                    104:                                                   }
                    105:              ;
                    106: 
                    107: block        : block F_PLUS   term                { $$ = symbols_op($1, $3, ADD_op);  }
                    108:              | block F_MINUS  term                { $$ = symbols_op($1, $3, SUB_op);  }
1.9     ! albertel  109:              | F_MINUS block                       { $$ = negate($2); }
1.1       albertel  110:              | term                               { $$ = $1; }
                    111:              | F_ERROR                            { FormulaParseOK = 0; FMLDBUG_PR1("[F_ERROR]\n"); return 0;}
                    112:              | error                              { FormulaParseOK = 0; FMLDBUG_PR1("[ERROR]\n"); return 0;  }
                    113:              ;
                    114: 
1.9     ! albertel  115: term         : term   F_MULT basic_constr         { $$ = symbols_op($1, $3, MUL_op);  }
        !           116:              | term   F_MULT F_MINUS basic_constr { $$ = symbols_op($1, negate($4), MUL_op);  }
        !           117:              | term   F_DIV  basic_constr         { $$ = symbols_op($1, $3, DIV_op);  }
        !           118:              | term   F_DIV  F_MINUS basic_constr { $$ = symbols_op($1, negate($4), DIV_op);  }
        !           119:              | term   F_MOD  basic_constr         { $$ = symbols_op($1, $3, IDIV_op); }
        !           120:              | term   F_MOD  F_MINUS basic_constr { $$ = symbols_op($1, negate($4), IDIV_op); }
1.1       albertel  121:              | basic_constr                       { $$ = $1; }
                    122:              ;
                    123: 
                    124: basic_constr : basic_constr  F_POW   basic_item   { $$ = f_symbol_pow($1,$3);
                    125:                                                     FMLDBUG_PR3("[%.16g ^ %.16g] ",$1->s_real,$3->s_real);       }
1.9     ! albertel  126:              | basic_constr F_POW F_MINUS basic_item   { $$ = f_symbol_pow($1,negate($4));
        !           127:                                                     FMLDBUG_PR3("[%.16g ^ %.16g] ",$1->s_real,$4->s_real);       }
1.1       albertel  128:              | basic_item                         { $$ = $1; }
                    129:              ;
                    130: 
                    131: arg_list     : arg_list F_COMMA  block            { $$ = $1;
                    132:                                                     $$->s_argc++;
                    133:                                                     $$->s_argp = addto_arglist($1->s_argp, $3);
                    134:                                                   }
                    135:              | block                              { $$ = $1;
                    136:                                                     $$->s_argc = 1;
                    137:                                                     $$->s_argp = new_arglist($1);
                    138:                                                   }
                    139:              ;
                    140: 
                    141: basic_item   : F_ID F_LPAR F_RPAR                 {  int tmp;
                    142:                                          
                    143:                                                      Func_idx--;
                    144:                                                      if(Func_idx >= 0 ) {
                    145:                                                        tmp = match_function(FuncStack[Func_idx].s_name,0);
                    146:                                                        $$ = do_function(tmp, 0, NULL );
                    147:                                                        capa_mfree(FuncStack[Func_idx].s_name);
                    148:                                                      }
                    149:                                                   }
                    150:              | F_ID F_LPAR arg_list  F_RPAR       {  int  tmp;
                    151:                                          
                    152:                                                      Func_idx--;
                    153:                                                      if(Func_idx >= 0 ) {
                    154:                                                         tmp = match_function(FuncStack[Func_idx].s_name,$3->s_argc);
                    155: 					                $$ = do_function(tmp, $3->s_argc, $3->s_argp);
                    156: 					                capa_mfree(FuncStack[Func_idx].s_name);
                    157: 					                free_arglist($3->s_argp);
1.7       albertel  158: 							$3->s_argp=NULL;
1.1       albertel  159:                                                       }
                    160:                                                   }
                    161:              | V_ID                               { FMLDBUG_PR3("[V %s = %.16g] ",$1->s_name, $1->s_real);
                    162:                                                     $$ = $1;
                    163:                                                   }
                    164:              | F_PLUS  basic_item                 { $$ = $2; }
                    165:              | F_NUMBER                           { FMLDBUG_PR2("[F %.16g] ",$1->s_real);
                    166:                                                     $$ = $1;
                    167:                                                   }
                    168:              | F_LPAR   block  F_RPAR             { $$ = $2; }
                    169:              ;
                    170: %%
                    171: void
                    172: fml_error(char *msg)
                    173: {
                    174:   FormulaParseOK=0;
                    175:   printf("Error Parsing: %s\n",msg);
                    176:   
                    177: }
                    178: /* ---------------------------------------------------- */
1.9     ! albertel  179: Symbol* negate(Symbol* symb) 
        !           180: {
        !           181:   Symbol* temp=symb;
        !           182:   switch(symb->s_type) {
        !           183:   case I_VAR:      temp = (Symbol *)capa_malloc(sizeof(Symbol),1);
        !           184:     temp->s_type = I_CONSTANT;
        !           185:   case I_CONSTANT: temp->s_int = - symb->s_int; break;
        !           186:   case R_VAR: temp = (Symbol *)capa_malloc(sizeof(Symbol),1);
        !           187:     temp->s_type = R_CONSTANT;
        !           188:   case R_CONSTANT: temp->s_real =   (-1.0)*(symb->s_real); 
        !           189:     break;
        !           190:   case S_VAR:
        !           191:   case S_CONSTANT: break;
        !           192:   default:         break;
        !           193:   }
        !           194:   return temp;
        !           195: }
        !           196: 
1.1       albertel  197: Symbol *
                    198: f_symbol_pow(ap,bp) Symbol *ap; Symbol *bp;
                    199: {
                    200:   Symbol *cp;
                    201:   double  a, b;
                    202:   int     error = 0;
                    203:   
                    204:   cp = NULL;
                    205:   switch(ap->s_type) {
                    206:      case I_VAR:      a = (double)(ap->s_int);
                    207:          break;
                    208:      case I_CONSTANT: a = (double)(ap->s_int); capa_mfree((char *)ap);
                    209:          break;
                    210:      case R_VAR:      a = ap->s_real;
                    211:          break;
                    212:      case R_CONSTANT: a = ap->s_real;   capa_mfree((char *)ap);
                    213:          break;
                    214:      case S_VAR:
                    215:      case S_CONSTANT: 
                    216:      default:         error = 1;  break;
                    217:   }
                    218:   switch(bp->s_type) {
                    219:      case I_VAR:      b = (double)(bp->s_int);
                    220:          break;
                    221:      case I_CONSTANT: b = (double)(bp->s_int);  capa_mfree((char *)bp);
                    222:          break;
                    223:      case R_VAR:      b = bp->s_real;
                    224:          break;
                    225:      case R_CONSTANT: b = bp->s_real;   capa_mfree((char *)bp);
                    226:          break;
                    227:      case S_VAR:
                    228:      case S_CONSTANT: 
                    229:      default:         error = 1; break;
                    230:   }
1.4       albertel  231:   if ((!(((double)((int)b)) == b)) && (a < 0.0)) {
                    232:     error = 1;
                    233:   }
1.1       albertel  234:   if (!error) {
                    235:     cp = (Symbol *)capa_malloc(sizeof(Symbol),1);
                    236:     cp->s_type = R_CONSTANT;
                    237:     cp->s_real = pow(a,b);
                    238:     
                    239:   }
                    240:   return (cp);
                    241: }
                    242: 
                    243: /* ============================================================================= */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>