exptrans.cpp

00001 //
00002 //##################################################################
00003 //                  CLASS  EXPRESSION_TRANSFORM  SOURCE
00004 //##################################################################
00005 //
00006 //                  Chris Anderson 9/10/96 (C) UCLA
00007 //
00008 
00009 #include <math.h>
00010 #include <iostream>
00011 #include <string>
00012 using namespace std;
00013 
00014 #include "exptrans.h"
00015 #include "OpLib.h"
00016 
00017 //
00018 // Bug Fix 02/08/99 : Changed priority of ^ so that it is evaluated
00019 // before unary + and - (so that -x^2 = (-1)*x^2. 
00020 // 
00021 // Bug Fix 02/03/04 : Fixed it so that variables starting with
00022 //                    digits (e.g. 2x) cause an exception to be thrown.
00023 //
00024 //##################################################################
00025 //                          CONSTRUCTORS
00026 //##################################################################
00027 //
00028 //
00029 expressionTransform::expressionTransform()
00030 {
00031    variableCount = 0;
00032    constantCount = 0;
00033 
00034    executionArray     = 0;
00035    executionArraySize = 0;
00036 
00037    sNames             = 0;
00038    symbolCount        = 0;
00039 
00040    evaluationDataSize = 0;
00041 
00042    opLib              = 0;
00043 
00044 }
00045 
00046 expressionTransform::expressionTransform(const expressionTransform& E)
00047 {
00048         variableCount = E.variableCount;
00049         constantCount = E.constantCount;
00050     symbolCount   = E.symbolCount;
00051 
00052     evaluationDataSize = E.evaluationDataSize;
00053 
00054     executionArraySize = E.executionArraySize;
00055     executionArray     = new long[executionArraySize];
00056 
00057     sNames             = new char*[symbolCount];
00058 
00059     int i;
00060     for(i=0; i< executionArraySize; i++)
00061     executionArray[i] = E.executionArray[i];
00062 
00063     for(i=0; i< symbolCount; i++)
00064     {
00065     sNames[i] = new char[strlen(E.sNames[i])+1];
00066     strcpy(sNames[i],E.sNames[i]);
00067     }
00068 
00069     opLib = E.opLib;
00070 }
00071 
00072 
00073 expressionTransform::expressionTransform(char** V, int Vcount, char* S,
00074 CAMoperatorLib* OLib)
00075 {
00076     char** C   = 0;
00077     int Ccount = 0;
00078     opLib      = OLib;
00079         createTransform(V, Vcount, C, Ccount, S);
00080 }
00081 
00082 expressionTransform::expressionTransform(char** V, int Vcount,
00083 char** C, int Ccount, char* S, CAMoperatorLib* OLib)
00084 {
00085     opLib      = OLib;
00086         createTransform(V, Vcount, C, Ccount, S);
00087 }
00088 //
00089 //##################################################################
00090 //                          DESTRUCTOR
00091 //##################################################################
00092 //
00093 expressionTransform::~expressionTransform()
00094 {
00095         destroy();
00096 }
00097 
00098 void expressionTransform::destroy()
00099 {
00100    if(executionArray != 0) delete [] executionArray;
00101 
00102    int i;
00103    if(sNames         != 0)
00104    {
00105    for(i=0; i< symbolCount; i++) if(sNames[i] != 0) delete [] sNames[i];
00106    delete [] sNames;
00107    }
00108 
00109    variableCount = 0;
00110    constantCount = 0;
00111    symbolCount   = 0;
00112 
00113    executionArraySize = 0;
00114    evaluationDataSize = 0;
00115 
00116    sNames    = 0;
00117    opLib     = 0;
00118 }
00119 //
00120 //##################################################################
00121 //                             INITIALIZE
00122 //##################################################################
00123 //
00124 int expressionTransform::initialize()
00125 {
00126     destroy();
00127     return 0;
00128 }
00129 
00130 int expressionTransform::initialize(char** V, int Vcount, char* S,
00131 CAMoperatorLib* OLib)
00132 {
00133     destroy();
00134     char** C   = 0;
00135     int Ccount = 0;
00136     opLib      = OLib;
00137 
00138     int    initReturn = createTransform(V, Vcount, C, Ccount, S);
00139     return initReturn;
00140 }
00141 
00142 int expressionTransform::initialize(char** V, int Vcount, char** C, int Ccount, char* S,
00143 CAMoperatorLib* OLib)
00144 {
00145     destroy();
00146     opLib       = OLib;
00147     int    initReturn = createTransform(V, Vcount, C, Ccount, S);
00148     return initReturn;
00149 }
00150 //
00151 //##################################################################
00152 //                          CREATE_TRANSFROM
00153 //##################################################################
00154 //
00155 int expressionTransform::createTransform(char** V, int Vcount, char** C, int Ccount, char* expressionString)
00156 {
00157 //
00158 //  Capture Input Data
00159 //
00160     variableCount = Vcount;
00161     constantCount = Ccount;
00162     char** vNames = V;
00163         char** cNames = C;
00164     char* inputS  = expressionString;
00165 //
00166 //
00167 //
00168    int  i;  int j;  int k;
00169    char* Sptr;
00170 //
00171 //######################################################################
00172 //
00173 //   SEPARATE EXPRESSION INTO TOKENS
00174 //
00175 //######################################################################
00176 //
00177     char* S             = new char[2*strlen(inputS) + 1];
00178     S[2*strlen(inputS)] = '\0';
00179 
00180     int separateReturn;
00181     separateReturn = separateIntoTokens(inputS,S);
00182     if(separateReturn != 0) {delete [] S; return separateReturn;}
00183 
00184 //   cout << S << endl;
00185 //
00186 //      Insert string terminators between tokens
00187 //
00188     long  Ssize = (long)strlen(S);
00189     for(i=0; i < Ssize; i++) if(S[i] == ' ') S[i] = '\0';
00190 //
00191 //  Count tokens
00192 //
00193     long tokenCount = 0;
00194     Sptr = S;
00195     while(Sptr < (S + Ssize - 1))
00196     {
00197     tokenCount++;
00198     Sptr = Sptr + strlen(Sptr) + 1;
00199     }
00200     if(tokenCount == 0){delete [] S;  return 1;}
00201 //
00202 //######################################################################
00203 //
00204 //   ENCODE TOKENS INTO ITERMEDIATE EXPRESSION CODE
00205 //
00206 //######################################################################
00207 //
00208     long* expressionCode = new long[2*tokenCount];
00209 //
00210 //  Count numerical constants
00211 //
00212     Sptr = S;
00213     long numericCount = 0;
00214     while(Sptr < (S + Ssize - 1))
00215     {
00216     if((((int(Sptr[0]) >= 48)&&(int(Sptr[0]) <= 57)))
00217     ||(Sptr[0] == '.'))
00218     {numericCount++;}
00219     Sptr = Sptr + strlen(Sptr) + 1;
00220     }
00221 //
00222 //  Create an array of names for
00223 //  variables, symbolic constants, and numeric constants
00224 //
00225 //  The indices of these symbols match the corresponding
00226 //  index of the data array used to store their values.
00227 //
00228     symbolCount   = variableCount + constantCount + numericCount;
00229     sNames = new char*[symbolCount];
00230 
00231     for(i = 0; i < variableCount; i++)
00232     {
00233       sNames[i] = new char[strlen(vNames[i]) + 1];
00234       strcpy(sNames[i],vNames[i]);
00235     }
00236     for(i = variableCount, j = 0; i < variableCount + constantCount; j++,i++)
00237     {
00238       sNames[i] = new char[strlen(cNames[j]) + 1];
00239       strcpy(sNames[i],cNames[j]);
00240     }
00241 
00242     Sptr = S;
00243     i = variableCount + constantCount;
00244     while(Sptr < (S + Ssize - 1))
00245     {
00246     if((((int(Sptr[0]) >= 48)&&(int(Sptr[0]) <= 57)))
00247     ||(Sptr[0] == '.'))
00248     {
00249      sNames[i] = new char[strlen(Sptr) + 1];
00250      strcpy(sNames[i],Sptr);
00251      i++;
00252     }
00253     Sptr = Sptr + strlen(Sptr) + 1;
00254     }
00255     
00256     long expressionCodeSize;
00257 
00258     int encodeReturn;
00259     encodeReturn = encodeExpression(S,Ssize,sNames,variableCount, constantCount,
00260     symbolCount,expressionCode,expressionCodeSize);
00261     if(encodeReturn != 0)
00262     {delete [] S; delete [] expressionCode; return encodeReturn;}
00263 //
00264 //  code to check encoding : output should match input string
00265 //
00266 /*
00267         for(i = 0; i < expressionCodeSize; i=i+2)
00268     {
00269     if(expressionCode[i] == VAR)
00270     { cout <<  expressionCode[i+1] << "  "; }
00271     else if(expressionCode[i] == DELIM)
00272     {
00273     if(expressionCode[i+1] == LEFTP)  cout << "(";
00274     if(expressionCode[i+1] == RIGHTP) cout << ")";
00275     if(expressionCode[i+1] == COMMA)  cout << ",";
00276     }
00277     else if(expressionCode[i] > 0)
00278     {
00279     cout << opLib->getOperatorSymbol(expressionCode[i+1]);
00280     cout << expressionCode[i+1] << "  ";
00281     }}
00282     cout << endl << endl << endl;
00283 */
00284 //
00285 //
00286 //######################################################################
00287 //
00288 //   ERROR CHECKING
00289 //
00290 //######################################################################
00291 //
00292     int parenthesisCheck = 0;
00293         for(i = 0; i < expressionCodeSize; i+=2)
00294     {
00295     if(expressionCode[i] == DELIM) parenthesisCheck  += expressionCode[i+1];
00296     }
00297     if(parenthesisCheck != 0)
00298     {
00299     cerr << endl << " Error : Unbalanced Paranthesis  " <<  endl <<endl;
00300     cerr << " Offending String :  " << inputS << endl;
00301     errorHandler();  delete [] S; delete [] expressionCode; return 1;
00302     }
00303 //
00304 //######################################################################
00305 //
00306 //   CREATE EXECUTION CODE : PACK INTO EXECUTIONARRAY
00307 //
00308 //######################################################################
00309 //
00310 //
00311 //  Count operators and arguments
00312 //
00313 //  Create storage space for executionArray
00314 //
00315     long opCount  = 0;
00316     long argCount = 0;
00317         for(i=0; i < expressionCodeSize; i+=2)
00318     {
00319     if(expressionCode[i] > 0)
00320     {
00321     opCount++;
00322     argCount +=
00323     opLib->getOperatorArgCount(expressionCode[i+1]) + 1;
00324     }}
00325 
00326     executionArraySize = 2*opCount + argCount;
00327 //
00328 //  Treat expressions with just one symbol 
00329 //  (Modification  2/26/97)
00330 //  (Modificaiton 10/28/00)
00331 //
00332     if(executionArraySize == 0)
00333     {
00334      executionArraySize = 4;
00335      executionArray     = new long[executionArraySize];
00336      executionArray[0]  = 0;  // set operand to unary +
00337      executionArray[1]  = 2;  // two arguments
00338 
00339      if(expressionCodeSize == 2)              // no parenthesis
00340      {
00341      executionArray[2]  = expressionCode[1];
00342      }
00343      if(expressionCodeSize == 6)              // parenthesis
00344      {
00345      executionArray[2]  = expressionCode[3];
00346      }
00347      executionArray[3]  = symbolCount;
00348      evaluationDataSize = symbolCount + 1;
00349      delete [] expressionCode;
00350      delete [] S;
00351      return 0;
00352     }
00353 
00354     executionArray     = new long[executionArraySize];
00355 
00356     long  executionIndex = 0;
00357     long  dataIndex      = symbolCount - 1;
00358 
00359     int   istart;
00360     int   iend;
00361 //
00362 //  Scan for paranthesis depth
00363 //
00364         int pDepth    = 0;
00365     for(i=0; i < expressionCodeSize; i+=2)
00366     {
00367     if((expressionCode[i] == DELIM)&&(expressionCode[i+1]== LEFTP)) pDepth++;
00368     }
00369 //
00370 //  Setup up execution sequences for each depth of paranthesis
00371 //
00372     int pIndex;  int jp;
00373     int sReturn;
00374     for(k = pDepth; k >= 1; k--)
00375     {
00376      pIndex = 0;
00377      for(j = 0; j < expressionCodeSize; j+=2)
00378      {
00379      if((expressionCode[j] == DELIM)&&(expressionCode[j+1]== LEFTP)) pIndex++;
00380 
00381      if(pIndex == k)
00382      {
00383      expressionCode[j] = NOOP; expressionCode[j+1] = NOOP;  // consume (
00384      istart = j;
00385      jp = j+2;
00386      while(!((expressionCode[jp] == DELIM)&&(expressionCode[jp+1] == RIGHTP)))
00387      {jp+=2;}
00388      iend   = jp;
00389      expressionCode[jp] = NOOP;expressionCode[jp+1] = NOOP; // consume )
00390      sReturn = setupEvaluation(expressionCode,istart,iend,  // process
00391                      executionArray,executionIndex, dataIndex);
00392      if(sReturn != 0){delete [] S; delete [] expressionCode; return sReturn;}
00393      pIndex--;
00394      }}
00395     }
00396 //
00397 //  Do pDepth == 0 directly
00398 //
00399     istart   = 0;
00400     iend     = expressionCodeSize;
00401     sReturn = setupEvaluation(expressionCode,istart,iend,executionArray,
00402                     executionIndex, dataIndex);
00403     if(sReturn != 0){delete [] S; delete [] expressionCode; return sReturn;}
00404 //
00405 //  set evaluationDataSize required
00406 //
00407     evaluationDataSize = dataIndex+1;
00408 //
00409 //  Check expressioncode to see only one operand left
00410 //
00411     int resultCount = 0;
00412         for(i = 0; i < expressionCodeSize; i+=2)
00413     {
00414     if(expressionCode[i] != NOOP) resultCount++;
00415     }
00416     if(resultCount != 1)
00417     {
00418       cerr << endl << " Illegal Expression " <<  endl <<endl;
00419       cerr << " Offending String :  " << inputS << endl;
00420       errorHandler(); delete [] S; delete [] expressionCode; return 1;    
00421     }
00422 
00423 //
00424 //######################################################################
00425 //
00426 //   CLEAN UP
00427 //
00428 //######################################################################
00429 //
00430 //
00431 
00432     delete [] expressionCode;
00433     delete [] S;
00434     return 0;
00435 }
00436 //
00437 //##################################################################
00438 //                         SETUPEVALUATION
00439 //##################################################################
00440 //
00441 
00442 int expressionTransform::setupEvaluation(long* expressionCode,
00443 int istart, int iend,long* executionArray,long& executionIndex,
00444 long& dataIndex)
00445 {
00446 //
00447 //  This routine repeatedly scans the expressionCode from left
00448 //  to right and sets up the execution pointers and indices.
00449 //
00450 //  The expressionCode is scanned from i = istart to i < iend;
00451 //
00452 //  The execution sequence is coded into executionArray
00453 //  in the form :
00454 //
00455 //  [operatorIndex][argument Count][ ...argument indices ... ]
00456 //
00457 //
00458 //  It is assumed that the input expression code contains no
00459 //  paranthesis.
00460 //
00461     int i; int j; int k;
00462     long argIndex; long argIndexLeft; long argIndexRight;
00463     int argCount;
00464 //
00465 //  remove ,'s
00466 //
00467         for(i = istart; i < iend; i=i+2)
00468     {
00469     if((expressionCode[i] == DELIM)&&(expressionCode[i+1]== COMMA))
00470     {expressionCode[i] = NOOP; expressionCode[i+1] = NOOP;}
00471     }
00472 //
00473 //  Function calls (priority 1)
00474 //
00475         for(i = istart; i < iend; i= i+2)
00476     {
00477     if(expressionCode[i] == 1)
00478     {
00479     //
00480     // set function call
00481     //
00482     argCount = opLib->getOperatorArgCount(expressionCode[i+1]);
00483     executionArray[executionIndex] = expressionCode[i+1]; executionIndex++;
00484     executionArray[executionIndex] = argCount + 1;        executionIndex++;
00485     //
00486     // scan right for argCount arguments and pack indices
00487     //
00488     k = 0;
00489         for(j=i+2; j < iend; j=j+2)
00490     {
00491       if(expressionCode[j] != NOOP)
00492       {
00493       if(expressionCode[j] != VAR)
00494       {
00495       cerr << endl << " Error : Incorrect Number of Arguments  " <<  endl <<endl;
00496       cerr << " Offending Operator :  "
00497       << opLib->getOperatorSymbol(expressionCode[i+1]) << endl;
00498       errorHandler(); return 1;
00499       }
00500       else
00501       {
00502       argIndex            = expressionCode[j+1];   // get location
00503       expressionCode[j]   = NOOP;                  // consume argument
00504       expressionCode[j+1] = NOOP;
00505       executionArray[executionIndex] = argIndex; executionIndex++;
00506       k++;
00507       if(k == argCount) j = iend;
00508       }}
00509     }
00510     //
00511     // ran off end looking for arguments
00512     //
00513     if(k!= argCount)
00514     {
00515       cerr << endl << " Error : Incorrect Number of Arguments  " <<  endl <<endl;
00516       cerr << " Offending Operator :  "
00517       << opLib->getOperatorSymbol(expressionCode[i+1]) << endl;
00518       errorHandler(); return 1;
00519     }
00520     //
00521     // set pointer to return argument
00522     //
00523     dataIndex++;
00524     executionArray[executionIndex] =  dataIndex;  executionIndex++;
00525     //
00526     // replace operator code by pointer to it's result
00527     //
00528     expressionCode[i]   = VAR;
00529     expressionCode[i+1] = dataIndex;
00530     }}
00531 
00532 //
00533 //  Exponentiation (priority 2)
00534 //
00535     for(i=istart; i < iend; i= i+2)
00536     {
00537 
00538     if(expressionCode[i] == 2)
00539     {
00540     //
00541     // set function call
00542     //
00543     executionArray[executionIndex] = expressionCode[i+1]; executionIndex++;
00544     executionArray[executionIndex] = 3;                   executionIndex++;
00545     //
00546     // scan right for arguments
00547     //
00548     for(j=i+2; j < iend; j=j+2)
00549     {
00550       if(expressionCode[j] != NOOP)
00551       {
00552       if(expressionCode[j] != VAR)
00553       {
00554       cerr << endl << " Error : Incorrect Number of Arguments  "
00555            <<  endl << endl;
00556       cerr << " Offending Operator :  "
00557       << opLib->getOperatorSymbol(expressionCode[i+1]) << endl;
00558       errorHandler(); return 1;
00559       }
00560       else
00561       {
00562       argIndexRight       = expressionCode[j+1];   // get location
00563       expressionCode[j]   = NOOP;                  // consume argument
00564       expressionCode[j+1] = NOOP;
00565       j = iend;
00566       }}
00567     }
00568     //
00569     // scan left for arguments
00570     //
00571     for(j=i-2; j >= istart; j=j-2)
00572     {
00573       if(expressionCode[j] != NOOP)
00574       {
00575       if(expressionCode[j] != VAR)
00576       {
00577       cerr << endl << " Error : Incorrect Number of Arguments  "
00578            <<  endl <<endl;
00579       cerr << " Offending Operator :  "
00580       << opLib->getOperatorSymbol(expressionCode[i+1]) << endl;
00581       errorHandler(); return 1;
00582       }
00583       else
00584       {
00585       argIndexLeft        = expressionCode[j+1];   // get location
00586       expressionCode[j]   = NOOP;                  // consume argument
00587       expressionCode[j+1] = NOOP;
00588       j = istart;
00589       }}
00590     }
00591     //
00592     // set up evaluation pointers
00593     //
00594     dataIndex++;
00595     executionArray[executionIndex] = argIndexLeft;   executionIndex++;
00596     executionArray[executionIndex] = argIndexRight;  executionIndex++;
00597     executionArray[executionIndex] = dataIndex;      executionIndex++;
00598     //
00599     // replace operator code by pointer to it's result
00600     //
00601     expressionCode[i]  = VAR;
00602     expressionCode[i+1]= dataIndex;
00603     }}
00604 //
00605 //  Unary Operators (priority 3)
00606 //
00607     for(i=istart; i < iend; i= i+2)
00608     {
00609 
00610     if(expressionCode[i] == 3)
00611     {
00612     //
00613     // set function call
00614     //
00615     executionArray[executionIndex] = expressionCode[i+1]; executionIndex++;
00616     executionArray[executionIndex] = 2;                   executionIndex++;
00617     //
00618     // scan right for arguments
00619     //
00620     for(j=i+2; j < iend; j=j+2)
00621     {
00622       if(expressionCode[j] != NOOP)
00623       {
00624       if(expressionCode[j] != VAR)
00625       {
00626       cerr << endl << " Error : Incorrect Number of Arguments  " <<  endl <<endl;
00627       cerr << " Offending Operator :  "
00628       << opLib->getOperatorSymbol(expressionCode[i+1]) << endl;
00629       errorHandler(); return 1;
00630       }
00631       else
00632       {
00633       argIndex = expressionCode[j+1];       // get location
00634       expressionCode[j]   = NOOP;           // consume argument
00635       expressionCode[j+1] = NOOP;
00636       j = iend;
00637       }}
00638     }
00639     //
00640     // set up evaluation pointers
00641     //
00642     dataIndex++;
00643     executionArray[executionIndex] = argIndex;  executionIndex++;
00644     executionArray[executionIndex] = dataIndex; executionIndex++;
00645     //
00646     // replace operator code by pointer to it's result
00647     //
00648     expressionCode[i]  = VAR;
00649     expressionCode[i+1]= dataIndex;
00650     }}
00651 //
00652 //  Binary Operators (priority 4,5)
00653 //
00654     for(k = 4; k <= 5; k++)
00655     {
00656 
00657     for(i=istart; i < iend; i= i+2)
00658     {
00659 
00660     if(expressionCode[i] == k)
00661     {
00662     //
00663     // set function call
00664     //
00665     executionArray[executionIndex] = expressionCode[i+1]; executionIndex++;
00666     executionArray[executionIndex] = 3;                   executionIndex++;
00667     //
00668     // scan right for arguments
00669     //
00670     for(j=i+2; j < iend; j=j+2)
00671     {
00672       if(expressionCode[j] != NOOP)
00673       {
00674       if(expressionCode[j] != VAR)
00675       {
00676       cerr << endl << " Error : Incorrect Number of Arguments  "
00677            <<  endl << endl;
00678       cerr << " Offending Operator :  "
00679       << opLib->getOperatorSymbol(expressionCode[i+1]) << endl;
00680       errorHandler(); return 1;
00681       }
00682       else
00683       {
00684       argIndexRight       = expressionCode[j+1];   // get location
00685       expressionCode[j]   = NOOP;                  // consume argument
00686       expressionCode[j+1] = NOOP;
00687       j = iend;
00688       }}
00689     }
00690     //
00691     // scan left for arguments
00692     //
00693     for(j=i-2; j >= istart; j=j-2)
00694     {
00695       if(expressionCode[j] != NOOP)
00696       {
00697       if(expressionCode[j] != VAR)
00698       {
00699       cerr << endl << " Error : Incorrect Number of Arguments  "
00700            <<  endl <<endl;
00701       cerr << " Offending Operator :  "
00702       << opLib->getOperatorSymbol(expressionCode[i+1]) << endl;
00703       errorHandler(); return 1;
00704       }
00705       else
00706       {
00707       argIndexLeft        = expressionCode[j+1];   // get location
00708       expressionCode[j]   = NOOP;                  // consume argument
00709       expressionCode[j+1] = NOOP;
00710       j = istart;
00711       }}
00712     }
00713     //
00714     // set up evaluation pointers
00715     //
00716     dataIndex++;
00717     executionArray[executionIndex] = argIndexLeft;   executionIndex++;
00718     executionArray[executionIndex] = argIndexRight;  executionIndex++;
00719     executionArray[executionIndex] = dataIndex;      executionIndex++;
00720     //
00721     // replace operator code by pointer to it's result
00722     //
00723     expressionCode[i]  = VAR;
00724     expressionCode[i+1]= dataIndex;
00725     }}
00726 
00727     }
00728 
00729     return 0;
00730 }
00731 //
00732 //##################################################################
00733 //                          ENCODE EXPRESSION
00734 //##################################################################
00735 //
00736 int expressionTransform::encodeExpression(char* S,long Ssize,
00737 char** sNames, long vCount, long cCount, long sCount,
00738 long* expressionCode,long& expressionCodeSize)
00739 {
00740 //
00741 // This routine encodes the tokenized experession in S into an
00742 // intermediate expression code. 
00743 //
00744 // Input parameters :
00745 //
00746 // S      = string in which tokens are separated by string terminators
00747 // Ssize  = total length of S in characters
00748 //
00749 // sNames = array of names of variables, symbolic and numeric constants
00750 // vCount = number of variable names
00751 // cCount = number of symbolic constant names
00752 // sCount = total number of symbol names
00753 //
00754 // Return Arguments :
00755 //
00756 // expressionCode     = array of longs to hold code (space allocated
00757 //                                          externally)
00758 //
00759 // expressionCodeSize = size of expressionCode array
00760 //
00761 
00762 //
00763 // Declare and initialize encoding variables
00764 //
00765     int i;
00766         char* Sptr;
00767     int tokenIndex = 0;
00768     int opIndex;
00769     int checkFlag;
00770     int unaryFlag;
00771 
00772     int unaryPlusIndex   = opLib->getUnaryOperatorIndex("+");
00773     int unaryMinusIndex  = opLib->getUnaryOperatorIndex("-");
00774     int binaryPlusIndex  = opLib->getBinaryOperatorIndex("+");
00775     int binaryMinusIndex = opLib->getBinaryOperatorIndex("-");
00776 
00777     int binaryTimesIndex  = opLib->getOperatorIndex("*");
00778     int binaryDivideIndex = opLib->getOperatorIndex("/");
00779     int binaryExpoIndex   = opLib->getOperatorIndex("^");
00780 
00781     Sptr  = S;
00782     char* Stoken;
00783 //
00784 //  Main encoding loop
00785 //
00786     while(Sptr < S + Ssize - 1)
00787     {
00788     Stoken = Sptr;
00789 //
00790 //      Delimiters : Coded (DELIM, Index of delimiter)
00791 //
00792         if (Stoken[0] == '(')
00793         {
00794          expressionCode[tokenIndex] = DELIM; tokenIndex++;
00795      expressionCode[tokenIndex] = LEFTP; tokenIndex++;
00796         }
00797         else if (Stoken[0] == ')')
00798         {
00799      expressionCode[tokenIndex] =  DELIM; tokenIndex++;
00800      expressionCode[tokenIndex] =  RIGHTP; tokenIndex++;
00801     }
00802         else if (Stoken[0] == ',')
00803         {
00804      expressionCode[tokenIndex] =  DELIM; tokenIndex++;
00805      expressionCode[tokenIndex] =  COMMA; tokenIndex++;
00806         }
00807 //
00808 //  Numerical Constants : Coded (VAR, Index of evaluationData value)
00809 //
00810     else if((((int(Stoken[0]) >= 48)&&(int(Stoken[0]) <= 57)))
00811     ||(Stoken[0] == '.'))
00812     {
00813     for(i = cCount + vCount; i < sCount; i++)
00814     {
00815     if(strcmp(Stoken,sNames[i]) == 0)
00816     {
00817        expressionCode[tokenIndex] = VAR;  tokenIndex++;
00818        expressionCode[tokenIndex] =   i;  tokenIndex++;
00819        i = sCount;
00820     }}
00821    }
00822 //
00823 //  Symbolic Tokens
00824 //
00825         else if(    ((int(Stoken[0]) >= 65)&&(int(Stoken[0]) <= 90))
00826              || ((int(Stoken[0]) >= 97)&&(int(Stoken[0]) <= 122))
00827            )
00828     {
00829 //
00830 //  Variables  : Coded (VAR, Index of evaluationData value)
00831 //
00832     checkFlag = 0;
00833     for(i = 0; i < vCount; i++)
00834     {
00835     if(strcmp(Stoken,sNames[i]) == 0)
00836     {
00837        expressionCode[tokenIndex] = VAR;  tokenIndex++;
00838        expressionCode[tokenIndex] =   i;  tokenIndex++;
00839        checkFlag = 1;
00840     }}
00841 //
00842 //  Symbolic Constants  : Coded (VAR, Index of evaluationData value)
00843 //
00844     if(checkFlag == 0)
00845     {
00846     for(i = vCount; i < vCount + cCount; i++)
00847     {
00848     if(strcmp(Stoken,sNames[i]) == 0)
00849     {
00850        expressionCode[tokenIndex] = VAR;  tokenIndex++;
00851        expressionCode[tokenIndex] =  i;   tokenIndex++;
00852        checkFlag = 1;
00853     }
00854     }}
00855 //
00856 //  Symbolic Operators : Coded (priority value, Index of Function)
00857 //
00858     if(checkFlag == 0)
00859     {
00860      opIndex = opLib->getOperatorIndex(Stoken);
00861      if(opIndex >= 0)
00862      {
00863       expressionCode[tokenIndex] =
00864       opLib->getOperatorPriority(opIndex);
00865       tokenIndex++;
00866       expressionCode[tokenIndex] =  opIndex;
00867       tokenIndex++;
00868       checkFlag = 1;
00869     }}
00870     //
00871     // Have a symbolic constant which doesn't match operator, variable
00872     // or a constant
00873     //
00874     if(checkFlag != 1)
00875     {
00876     cerr << endl << " Error : Illegal Symbol  " <<  endl <<endl;
00877     cerr << " Offending Symbol :  " << Stoken << endl;
00878     errorHandler();  return 1;
00879     }
00880     }
00881 //
00882 //  Algebraic Operators : Coded (priority value, Index of Function)
00883 //
00884         else if(Stoken[0] == '+')
00885     {
00886 
00887     if(tokenIndex == 0)                          // first operand
00888     { unaryFlag = 1;}
00889     else if
00890     (
00891     (expressionCode[tokenIndex  -2] == DELIM)&&     // delimiter
00892     ((expressionCode[tokenIndex -1] == LEFTP)||     //   (
00893     (expressionCode[tokenIndex  -1] == COMMA))      //   ,
00894     )
00895     { unaryFlag = 1;}
00896     else if
00897     (
00898     (expressionCode[tokenIndex  -2] > 0)&&                 // operand
00899     ((expressionCode[tokenIndex -1] == binaryPlusIndex)||  //   +
00900      (expressionCode[tokenIndex -1] == binaryMinusIndex)|| //   -
00901      (expressionCode[tokenIndex -1] == binaryDivideIndex)||//   /
00902      (expressionCode[tokenIndex -1] == binaryExpoIndex)||  //   +
00903      (expressionCode[tokenIndex -1] == binaryTimesIndex))  //   *
00904     )
00905     { unaryFlag = 1;}
00906     else
00907     {
00908     unaryFlag = 0;
00909     }
00910 
00911     if(unaryFlag == 1)
00912     {
00913       expressionCode[tokenIndex] =
00914       opLib->getOperatorPriority(unaryPlusIndex);
00915       tokenIndex++;
00916       expressionCode[tokenIndex] =  unaryPlusIndex;
00917       tokenIndex++;
00918     }
00919     else
00920     {
00921           expressionCode[tokenIndex] =
00922       opLib->getOperatorPriority(binaryPlusIndex);
00923       tokenIndex++;
00924       expressionCode[tokenIndex] =  binaryPlusIndex;
00925       tokenIndex++;
00926     }
00927     }
00928 //
00929 //
00930 //
00931     else if(Stoken[0] == '-')
00932     {
00933     if(tokenIndex == 0)                          // first operand
00934     { unaryFlag = 1;}
00935     else if
00936     (
00937     (expressionCode[tokenIndex  -2] == DELIM)&&     // delimiter
00938     ((expressionCode[tokenIndex -1] == LEFTP)||     //   (
00939     (expressionCode[tokenIndex  -1] == COMMA))      //   ,
00940     )
00941     { unaryFlag = 1;}
00942     else if
00943     (
00944     (expressionCode[tokenIndex  -2] > 0)&&                 // operand
00945     ((expressionCode[tokenIndex -1] == binaryPlusIndex)||  //   +
00946      (expressionCode[tokenIndex -1] == binaryMinusIndex)|| //   -
00947      (expressionCode[tokenIndex -1] == binaryDivideIndex)||//   /
00948      (expressionCode[tokenIndex -1] == binaryExpoIndex)||  //   +
00949      (expressionCode[tokenIndex -1] == binaryTimesIndex))  //   *
00950     )
00951     { unaryFlag = 1;}
00952     else
00953     {
00954     unaryFlag = 0;
00955     }
00956 
00957     if(unaryFlag == 1)
00958     {
00959       expressionCode[tokenIndex] =
00960       opLib->getOperatorPriority(unaryMinusIndex);
00961       tokenIndex++;
00962       expressionCode[tokenIndex] =  unaryMinusIndex;
00963       tokenIndex++;
00964     }
00965     else
00966     {
00967           expressionCode[tokenIndex] =
00968       opLib->getOperatorPriority(binaryMinusIndex);
00969       tokenIndex++;
00970       expressionCode[tokenIndex] =  binaryMinusIndex;
00971       tokenIndex++;
00972     }
00973 //
00974 //                     *, /, ^
00975 //
00976     }
00977     else if((Stoken[0] == '*')||(Stoken[0] == '/')||(Stoken[0] == '^'))
00978     {
00979      opIndex = opLib->getOperatorIndex(Stoken);
00980      expressionCode[tokenIndex] =
00981      opLib->getOperatorPriority(opIndex);
00982      tokenIndex++;
00983      expressionCode[tokenIndex] =  opIndex;
00984      tokenIndex++;
00985     }
00986     else
00987     {
00988     cerr << endl << " Error : Illegal Symbol  " <<  endl <<endl;
00989     cerr << " Offending Symbol :  " << Stoken << endl;
00990     errorHandler();  return 1;
00991     }
00992  //
00993  // update token pointer
00994  //
00995     Sptr = Sptr + strlen(Sptr) + 1;
00996     }
00997 
00998     expressionCodeSize = tokenIndex;
00999     return 0;
01000  }
01001 //
01002 //##################################################################
01003 //                      SEPARATE_INTO_TOKENS
01004 //##################################################################
01005 //
01006 int expressionTransform::separateIntoTokens(char* sIn, char* S)
01007 {
01008 //
01009 //  This routine takes the string sIn and decomposes it into
01010 //  distinct tokens separated by single spaces " ". The storage for
01011 //  S must be declared externally (maximal size will be
01012 //  (2*strlen(sIn) + 1).  No error checking is done to see if S
01013 //  is of sufficient size.
01014 //
01015     char* sInput  = new char[strlen(sIn) + 1];  //  capture input string
01016     strcpy(sInput, sIn);                        //
01017 //   
01018     int i;
01019 //
01020 //  Remove Spaces
01021 //
01022     int  iMark = 0;
01023     for(i = 0; i < (int)strlen(sInput); i++)
01024     {
01025     if(sInput[i] != ' '){ sInput[iMark] = sInput[i]; iMark++; }
01026     }
01027     sInput[iMark] = '\0';
01028 //
01029 //  Insert Spaces
01030 //
01031     iMark = 0;
01032     for(i = 0; i < (int)strlen(sInput); i++)
01033     {
01034 //
01035 //  Operands and delimiters
01036 //
01037     if( ((int(sInput[i]) >= 40)&&(int(sInput[i]) <= 45))
01038         ||(sInput[i] == '/')
01039         ||(sInput[i] == '^')
01040       ) {S[iMark] = sInput[i]; iMark++; S[iMark] = ' '; iMark++;}
01041 
01042     else
01043 //
01044 //  Variables and symbolic constants
01045 //
01046     if(    ((int(sInput[i]) >= 65)&&(int(sInput[i]) <= 90))
01047         || ((int(sInput[i]) >= 97)&&(int(sInput[i]) <= 122))
01048       )
01049     {
01050     while
01051       (    ((int(sInput[i]) >= 65)&&(int(sInput[i]) <= 90))
01052         || ((int(sInput[i]) >= 97)&&(int(sInput[i]) <= 122))
01053         || ((int(sInput[i]) >= 48)&&(int(sInput[i]) <= 57))
01054       ){ S[iMark] = sInput[i]; iMark++; i++; }
01055       i--;
01056       S[iMark] = ' '; iMark++;
01057     }
01058 //
01059 //  Digits
01060 //
01061     else
01062     if ((((int(sInput[i]) >= 48)&&(int(sInput[i]) <= 57)))
01063       ||(sInput[i] == '.'))
01064     {
01065      while((int(sInput[i]) >= 48)&&(int(sInput[i]) <= 57))
01066      {S[iMark] = sInput[i]; iMark++; i++; }
01067  //
01068  //  Decimal Numbers
01069  //
01070      if(sInput[i] == '.')
01071      {
01072      S[iMark] = '.'; iMark++; i++;
01073      while((int(sInput[i]) >= 48)&&(int(sInput[i]) <= 57))
01074      {S[iMark] = sInput[i]; iMark++; i++; }
01075      }
01076  //
01077  //  Exponential Notation
01078  //
01079      if((sInput[i] == 'e')||(sInput[i] == 'E'))
01080      {
01081      S[iMark] = 'e'; iMark++; i++;
01082      if(sInput[i] == '+'){S[iMark] = '+'; iMark++; i++;}
01083      if(sInput[i] == '-'){S[iMark] = '-'; iMark++; i++;}
01084      while((int(sInput[i]) >= 48)&&(int(sInput[i]) <= 57))
01085      {S[iMark] = sInput[i]; iMark++; i++; }
01086      }
01087      else
01088 //
01089 //   Check for invalid numeric input 
01090 //
01091      if(   ((int(sInput[i]) >= 65)&&(int(sInput[i]) <= 90))
01092         || ((int(sInput[i]) >= 97)&&(int(sInput[i]) <= 122))
01093      )
01094      {
01095      cerr << endl << " Error : Illegal Symbol  " <<  endl <<endl;
01096      cerr << " Offending String :  " << sIn << endl << endl;
01097      cerr << " Offending Symbol :  " << sInput[i] << endl;
01098      errorHandler();  return 1;
01099      }
01100 //
01101 //  Insert Space
01102 //
01103      i--;
01104      S[iMark] = ' '; iMark++;
01105 
01106     }
01107     else
01108     {
01109     cerr << endl << " Error : Illegal Symbol  " <<  endl <<endl;
01110     cerr << " Offending String :  " << sIn << endl << endl;
01111     cerr << " Offending Symbol :  " << sInput[i] << endl;
01112     errorHandler();  return 1;
01113     }
01114 
01115     }
01116 //
01117 //  Close String  and clean up
01118 //
01119     S[iMark] = '\0';
01120     delete [] sInput;
01121     return 0;
01122 }
01123 
01124 //
01125 //##################################################################
01126 //                      Error Handler
01127 //##################################################################
01128 //
01129 void expressionTransform::errorHandler()
01130 {
01131     destroy();
01132 }

Generated on Wed Jan 14 09:18:14 2009 for DoubleVector by  doxygen 1.5.1-p1