Geant4 Cross Reference |
1 // -*- C++ -*- 1 // -*- C++ -*- 2 // ------------------------------------------- 2 // --------------------------------------------------------------------------- 3 3 4 #include "CLHEP/Evaluator/Evaluator.h" 4 #include "CLHEP/Evaluator/Evaluator.h" 5 5 6 #include <iostream> 6 #include <iostream> 7 #include <sstream> 7 #include <sstream> 8 #include <string> << 9 #include <cmath> // for std::pow() 8 #include <cmath> // for std::pow() 10 #include <stack> << 9 #include "CLHEP/Evaluator/stack.icc" 11 #include <unordered_map> << 10 #include "CLHEP/Evaluator/string.icc" >> 11 #include "CLHEP/Evaluator/hash_map.icc" 12 #include <string.h> 12 #include <string.h> 13 #include <ctype.h> 13 #include <ctype.h> 14 #include <errno.h> 14 #include <errno.h> 15 #include <stdlib.h> // for strtod() 15 #include <stdlib.h> // for strtod() 16 16 17 using std::string; << 18 using std::stack; << 19 << 20 //-------------------------------------------- 17 //--------------------------------------------------------------------------- 21 // Fix non ISO C++ compliant cast from pointer 18 // Fix non ISO C++ compliant cast from pointer to function 22 // to void*, which is a pointer to an object 19 // to void*, which is a pointer to an object 23 typedef void (*voidfuncptr)(); 20 typedef void (*voidfuncptr)(); 24 struct Item { 21 struct Item { 25 enum { UNKNOWN, VARIABLE, EXPRESSION, FUNCTI 22 enum { UNKNOWN, VARIABLE, EXPRESSION, FUNCTION } what; 26 double variable; 23 double variable; 27 string expression; 24 string expression; 28 // Fix non ISO C++ compliant cast from point 25 // Fix non ISO C++ compliant cast from pointer to function 29 // to void*, which is a pointer to an object 26 // to void*, which is a pointer to an object 30 //void *function; 27 //void *function; 31 voidfuncptr function; 28 voidfuncptr function; 32 29 33 Item() : what(UNKNOWN), variable(0 30 Item() : what(UNKNOWN), variable(0),expression(), function(0) {} 34 Item(double x) : what(VARIABLE), variable(x 31 Item(double x) : what(VARIABLE), variable(x),expression(), function(0) {} 35 Item(string x) : what(EXPRESSION),variable(0 32 Item(string x) : what(EXPRESSION),variable(0),expression(x),function(0) {} 36 Item(voidfuncptr x) : what(FUNCTION), varia 33 Item(voidfuncptr x) : what(FUNCTION), variable(0),expression(), function(x) {} 37 }; 34 }; 38 35 39 using pchar = char *; << 36 typedef char * pchar; 40 using dic_type = std::unordered_map<string, It << 37 typedef hash_map<string,Item> dic_type; 41 38 42 struct Struct { 39 struct Struct { 43 dic_type theDictionary; 40 dic_type theDictionary; 44 pchar theExpression; 41 pchar theExpression; 45 pchar thePosition; 42 pchar thePosition; 46 int theStatus; 43 int theStatus; 47 double theResult; 44 double theResult; 48 }; 45 }; 49 46 50 //-------------------------------------------- 47 //--------------------------------------------------------------------------- 51 #define EVAL HepTool::Evaluator 48 #define EVAL HepTool::Evaluator 52 49 53 #define REMOVE_BLANKS \ 50 #define REMOVE_BLANKS \ 54 for(pointer=name;;pointer++) if (!isspace(*poi 51 for(pointer=name;;pointer++) if (!isspace(*pointer)) break; \ 55 for(n=(int)strlen(pointer);n>0;n--) if (!isspa << 52 for(n=strlen(pointer);n>0;n--) if (!isspace(*(pointer+n-1))) break 56 53 57 #define SKIP_BLANKS \ 54 #define SKIP_BLANKS \ 58 for(;;pointer++) { \ 55 for(;;pointer++) { \ 59 c = (pointer > end) ? '\0' : *pointer; \ 56 c = (pointer > end) ? '\0' : *pointer; \ 60 if (!isspace(c)) break; \ 57 if (!isspace(c)) break; \ 61 } 58 } 62 59 63 #define EVAL_EXIT(STATUS,POSITION) endp = POSI 60 #define EVAL_EXIT(STATUS,POSITION) endp = POSITION; return STATUS 64 #define MAX_N_PAR 5 61 #define MAX_N_PAR 5 65 62 66 static const char sss[MAX_N_PAR+2] = "012345"; 63 static const char sss[MAX_N_PAR+2] = "012345"; 67 64 68 enum { ENDL, LBRA, OR, AND, EQ, NE, GE, GT, LE 65 enum { ENDL, LBRA, OR, AND, EQ, NE, GE, GT, LE, LT, 69 PLUS, MINUS, UNARY_PLUS, UNARY_MINUS, M 66 PLUS, MINUS, UNARY_PLUS, UNARY_MINUS, MULT, DIV, POW, RBRA, VALUE }; 70 67 71 static int engine(pchar, pchar, double &, pcha 68 static int engine(pchar, pchar, double &, pchar &, const dic_type &); 72 69 73 static int variable(const string & name, doubl 70 static int variable(const string & name, double & result, 74 const dic_type & dictionary) 71 const dic_type & dictionary) 75 /********************************************* 72 /*********************************************************************** 76 * 73 * * 77 * Name: variable 74 * Name: variable Date: 03.10.00 * 78 * Author: Evgeni Chernyaev 75 * Author: Evgeni Chernyaev Revised: * 79 * 76 * * 80 * Function: Finds value of the variable. 77 * Function: Finds value of the variable. * 81 * This function is used by operand( 78 * This function is used by operand(). * 82 * 79 * * 83 * Parameters: 80 * Parameters: * 84 * name - name of the variable. 81 * name - name of the variable. * 85 * result - value of the variable. 82 * result - value of the variable. * 86 * dictionary - dictionary of available vari 83 * dictionary - dictionary of available variables and functions. * 87 * 84 * * 88 ********************************************* 85 ***********************************************************************/ 89 { 86 { 90 dic_type::const_iterator iter = dictionary.f 87 dic_type::const_iterator iter = dictionary.find(name); 91 if (iter == dictionary.end()) 88 if (iter == dictionary.end()) 92 return EVAL::ERROR_UNKNOWN_VARIABLE; 89 return EVAL::ERROR_UNKNOWN_VARIABLE; 93 Item item = iter->second; 90 Item item = iter->second; 94 switch (item.what) { 91 switch (item.what) { 95 case Item::VARIABLE: 92 case Item::VARIABLE: 96 result = item.variable; 93 result = item.variable; 97 return EVAL::OK; 94 return EVAL::OK; 98 case Item::EXPRESSION: { 95 case Item::EXPRESSION: { 99 pchar exp_begin = (char *)(item.expression 96 pchar exp_begin = (char *)(item.expression.c_str()); 100 pchar exp_end = exp_begin + strlen(exp_b 97 pchar exp_end = exp_begin + strlen(exp_begin) - 1; 101 if (engine(exp_begin, exp_end, result, exp 98 if (engine(exp_begin, exp_end, result, exp_end, dictionary) == EVAL::OK) 102 return EVAL::OK; 99 return EVAL::OK; 103 else 100 else 104 return EVAL::ERROR_CALCULATION_ERROR; 101 return EVAL::ERROR_CALCULATION_ERROR; 105 } 102 } 106 default: 103 default: 107 return EVAL::ERROR_CALCULATION_ERROR; 104 return EVAL::ERROR_CALCULATION_ERROR; 108 } 105 } 109 } 106 } 110 107 111 static int function(const string & name, stack 108 static int function(const string & name, stack<double> & par, 112 double & result, const dic_type & dict 109 double & result, const dic_type & dictionary) 113 /********************************************* 110 /*********************************************************************** 114 * 111 * * 115 * Name: function 112 * Name: function Date: 03.10.00 * 116 * Author: Evgeni Chernyaev 113 * Author: Evgeni Chernyaev Revised: * 117 * 114 * * 118 * Function: Finds value of the function. 115 * Function: Finds value of the function. * 119 * This function is used by operand( 116 * This function is used by operand(). * 120 * 117 * * 121 * Parameters: 118 * Parameters: * 122 * name - name of the function. 119 * name - name of the function. * 123 * par - stack of parameters. 120 * par - stack of parameters. * 124 * result - value of the function. 121 * result - value of the function. * 125 * dictionary - dictionary of available vari 122 * dictionary - dictionary of available variables and functions. * 126 * 123 * * 127 ********************************************* 124 ***********************************************************************/ 128 { 125 { 129 unsigned long npar = par.size(); << 126 int npar = par.size(); 130 if (npar > MAX_N_PAR) return EVAL::ERROR_UNK 127 if (npar > MAX_N_PAR) return EVAL::ERROR_UNKNOWN_FUNCTION; 131 128 132 dic_type::const_iterator iter = dictionary.f 129 dic_type::const_iterator iter = dictionary.find(sss[npar]+name); 133 if (iter == dictionary.end()) return EVAL::E 130 if (iter == dictionary.end()) return EVAL::ERROR_UNKNOWN_FUNCTION; 134 Item item = iter->second; 131 Item item = iter->second; 135 132 136 double pp[MAX_N_PAR] = {0.0}; 133 double pp[MAX_N_PAR] = {0.0}; 137 for(unsigned long i=0; i<npar; ++i) { pp[i] << 134 for(int i=0; i<npar; i++) { pp[i] = par.top(); par.pop(); } 138 errno = 0; 135 errno = 0; 139 if (item.function == 0) return EVAL::E 136 if (item.function == 0) return EVAL::ERROR_CALCULATION_ERROR; 140 switch (npar) { 137 switch (npar) { 141 case 0: 138 case 0: 142 result = ((double (*)())item.function)(); 139 result = ((double (*)())item.function)(); 143 break; 140 break; 144 case 1: 141 case 1: 145 result = ((double (*)(double))item.functio 142 result = ((double (*)(double))item.function)(pp[0]); 146 break; 143 break; 147 case 2: 144 case 2: 148 result = ((double (*)(double,double))item. 145 result = ((double (*)(double,double))item.function)(pp[1], pp[0]); 149 break; 146 break; 150 case 3: 147 case 3: 151 result = ((double (*)(double,double,double 148 result = ((double (*)(double,double,double))item.function) 152 (pp[2],pp[1],pp[0]); 149 (pp[2],pp[1],pp[0]); 153 break; 150 break; 154 case 4: 151 case 4: 155 result = ((double (*)(double,double,double 152 result = ((double (*)(double,double,double,double))item.function) 156 (pp[3],pp[2],pp[1],pp[0]); 153 (pp[3],pp[2],pp[1],pp[0]); 157 break; 154 break; 158 case 5: 155 case 5: 159 result = ((double (*)(double,double,double 156 result = ((double (*)(double,double,double,double,double))item.function) 160 (pp[4],pp[3],pp[2],pp[1],pp[0]); 157 (pp[4],pp[3],pp[2],pp[1],pp[0]); 161 break; 158 break; 162 } 159 } 163 return (errno == 0) ? EVAL::OK : EVAL::ERROR 160 return (errno == 0) ? EVAL::OK : EVAL::ERROR_CALCULATION_ERROR; 164 } 161 } 165 162 166 static int operand(pchar begin, pchar end, dou 163 static int operand(pchar begin, pchar end, double & result, 167 pchar & endp, const dic_type & dictiona 164 pchar & endp, const dic_type & dictionary) 168 /********************************************* 165 /*********************************************************************** 169 * 166 * * 170 * Name: operand 167 * Name: operand Date: 03.10.00 * 171 * Author: Evgeni Chernyaev 168 * Author: Evgeni Chernyaev Revised: * 172 * 169 * * 173 * Function: Finds value of the operand. The o 170 * Function: Finds value of the operand. The operand can be either * 174 * a number or a variable or a funct 171 * a number or a variable or a function. * 175 * This function is used by engine() 172 * This function is used by engine(). * 176 * 173 * * 177 * Parameters: 174 * Parameters: * 178 * begin - pointer to the first character o 175 * begin - pointer to the first character of the operand. * 179 * end - pointer to the last character of 176 * end - pointer to the last character of the character string. * 180 * result - value of the operand. 177 * result - value of the operand. * 181 * endp - pointer to the character where t 178 * endp - pointer to the character where the evaluation stoped. * 182 * dictionary - dictionary of available vari 179 * dictionary - dictionary of available variables and functions. * 183 * 180 * * 184 ********************************************* 181 ***********************************************************************/ 185 { 182 { 186 pchar pointer = begin; 183 pchar pointer = begin; 187 int EVAL_STATUS; 184 int EVAL_STATUS; 188 char c; 185 char c; 189 186 190 // G E T N U M B E R 187 // G E T N U M B E R 191 188 192 if (!isalpha(*pointer)) { 189 if (!isalpha(*pointer)) { 193 errno = 0; 190 errno = 0; 194 result = strtod(pointer, (char **)(&pointe 191 result = strtod(pointer, (char **)(&pointer)); 195 if (errno == 0) { 192 if (errno == 0) { 196 EVAL_EXIT( EVAL::OK, --pointer ); 193 EVAL_EXIT( EVAL::OK, --pointer ); 197 }else{ 194 }else{ 198 EVAL_EXIT( EVAL::ERROR_CALCULATION_ERROR 195 EVAL_EXIT( EVAL::ERROR_CALCULATION_ERROR, begin ); 199 } 196 } 200 } 197 } 201 198 202 // G E T N A M E 199 // G E T N A M E 203 200 204 while(pointer <= end) { 201 while(pointer <= end) { 205 c = *pointer; 202 c = *pointer; 206 if (c != '_' && !isalnum(c)) break; 203 if (c != '_' && !isalnum(c)) break; 207 pointer++; 204 pointer++; 208 } 205 } 209 c = *pointer; 206 c = *pointer; 210 *pointer = '\0'; 207 *pointer = '\0'; 211 string name(begin); 208 string name(begin); 212 *pointer = c; 209 *pointer = c; 213 210 214 // G E T V A R I A B L E 211 // G E T V A R I A B L E 215 212 216 result = 0.0; 213 result = 0.0; 217 SKIP_BLANKS; 214 SKIP_BLANKS; 218 if (c != '(') { 215 if (c != '(') { 219 EVAL_STATUS = variable(name, result, dicti 216 EVAL_STATUS = variable(name, result, dictionary); 220 EVAL_EXIT( EVAL_STATUS, (EVAL_STATUS == EV 217 EVAL_EXIT( EVAL_STATUS, (EVAL_STATUS == EVAL::OK) ? --pointer : begin); 221 } 218 } 222 219 223 // G E T F U N C T I O N 220 // G E T F U N C T I O N 224 221 225 stack<pchar> pos; // positio 222 stack<pchar> pos; // position stack 226 stack<double> par; // paramet 223 stack<double> par; // parameter stack 227 double value; 224 double value; 228 pchar par_begin = pointer+1, par_end 225 pchar par_begin = pointer+1, par_end; 229 226 230 for(;;pointer++) { 227 for(;;pointer++) { 231 c = (pointer > end) ? '\0' : *pointer; 228 c = (pointer > end) ? '\0' : *pointer; 232 switch (c) { 229 switch (c) { 233 case '\0': 230 case '\0': 234 EVAL_EXIT( EVAL::ERROR_UNPAIRED_PARENTHE 231 EVAL_EXIT( EVAL::ERROR_UNPAIRED_PARENTHESIS, pos.top() ); 235 case '(': 232 case '(': 236 pos.push(pointer); break; 233 pos.push(pointer); break; 237 case ',': 234 case ',': 238 if (pos.size() == 1) { 235 if (pos.size() == 1) { 239 par_end = pointer-1; 236 par_end = pointer-1; 240 EVAL_STATUS = engine(par_begin, par_end, val 237 EVAL_STATUS = engine(par_begin, par_end, value, par_end, dictionary); 241 if (EVAL_STATUS == EVAL::WARNING_BLANK_STRIN 238 if (EVAL_STATUS == EVAL::WARNING_BLANK_STRING) 242 { EVAL_EXIT( EVAL::ERROR_EMPTY_PARAMETER, 239 { EVAL_EXIT( EVAL::ERROR_EMPTY_PARAMETER, --par_end ); } 243 if (EVAL_STATUS != EVAL::OK) 240 if (EVAL_STATUS != EVAL::OK) 244 { EVAL_EXIT( EVAL_STATUS, par_end ); } 241 { EVAL_EXIT( EVAL_STATUS, par_end ); } 245 par.push(value); 242 par.push(value); 246 par_begin = pointer + 1; 243 par_begin = pointer + 1; 247 } 244 } 248 break; 245 break; 249 case ')': 246 case ')': 250 if (pos.size() > 1) { 247 if (pos.size() > 1) { 251 pos.pop(); 248 pos.pop(); 252 break; 249 break; 253 }else{ 250 }else{ 254 par_end = pointer-1; 251 par_end = pointer-1; 255 EVAL_STATUS = engine(par_begin, par_end, val 252 EVAL_STATUS = engine(par_begin, par_end, value, par_end, dictionary); 256 switch (EVAL_STATUS) { 253 switch (EVAL_STATUS) { 257 case EVAL::OK: 254 case EVAL::OK: 258 par.push(value); 255 par.push(value); 259 break; 256 break; 260 case EVAL::WARNING_BLANK_STRING: 257 case EVAL::WARNING_BLANK_STRING: 261 if (par.size() != 0) 258 if (par.size() != 0) 262 { EVAL_EXIT( EVAL::ERROR_EMPTY_PARAMETER 259 { EVAL_EXIT( EVAL::ERROR_EMPTY_PARAMETER, --par_end ); } 263 break; 260 break; 264 default: 261 default: 265 EVAL_EXIT( EVAL_STATUS, par_end ); 262 EVAL_EXIT( EVAL_STATUS, par_end ); 266 } 263 } 267 EVAL_STATUS = function(name, par, result, di 264 EVAL_STATUS = function(name, par, result, dictionary); 268 EVAL_EXIT( EVAL_STATUS, (EVAL_STATUS == EVAL 265 EVAL_EXIT( EVAL_STATUS, (EVAL_STATUS == EVAL::OK) ? pointer : begin); 269 } 266 } 270 } 267 } 271 } 268 } 272 } 269 } 273 270 274 /********************************************* 271 /*********************************************************************** 275 * 272 * * 276 * Name: maker 273 * Name: maker Date: 28.09.00 * 277 * Author: Evgeni Chernyaev 274 * Author: Evgeni Chernyaev Revised: * 278 * 275 * * 279 * Function: Executes basic arithmetic operati 276 * Function: Executes basic arithmetic operations on values in the top * 280 * of the stack. Result is placed ba 277 * of the stack. Result is placed back into the stack. * 281 * This function is used by engine() 278 * This function is used by engine(). * 282 * 279 * * 283 * Parameters: 280 * Parameters: * 284 * op - code of the operation. 281 * op - code of the operation. * 285 * val - stack of values. 282 * val - stack of values. * 286 * 283 * * 287 ********************************************* 284 ***********************************************************************/ 288 static int maker(int op, stack<double> & val) 285 static int maker(int op, stack<double> & val) 289 { 286 { 290 if (val.size() < 2) return EVAL::ERROR_SYNTA 287 if (val.size() < 2) return EVAL::ERROR_SYNTAX_ERROR; 291 double val2 = val.top(); val.pop(); 288 double val2 = val.top(); val.pop(); 292 double val1 = val.top(); 289 double val1 = val.top(); 293 switch (op) { 290 switch (op) { 294 case OR: // o 291 case OR: // operator || 295 val.top() = (val1 || val2) ? 1. : 0.; 292 val.top() = (val1 || val2) ? 1. : 0.; 296 return EVAL::OK; 293 return EVAL::OK; 297 case AND: // o 294 case AND: // operator && 298 val.top() = (val1 && val2) ? 1. : 0.; 295 val.top() = (val1 && val2) ? 1. : 0.; 299 return EVAL::OK; 296 return EVAL::OK; 300 case EQ: // o 297 case EQ: // operator == 301 val.top() = (val1 == val2) ? 1. : 0.; 298 val.top() = (val1 == val2) ? 1. : 0.; 302 return EVAL::OK; 299 return EVAL::OK; 303 case NE: // o 300 case NE: // operator != 304 val.top() = (val1 != val2) ? 1. : 0.; 301 val.top() = (val1 != val2) ? 1. : 0.; 305 return EVAL::OK; 302 return EVAL::OK; 306 case GE: // o 303 case GE: // operator >= 307 val.top() = (val1 >= val2) ? 1. : 0.; 304 val.top() = (val1 >= val2) ? 1. : 0.; 308 return EVAL::OK; 305 return EVAL::OK; 309 case GT: // o 306 case GT: // operator > 310 val.top() = (val1 > val2) ? 1. : 0.; 307 val.top() = (val1 > val2) ? 1. : 0.; 311 return EVAL::OK; 308 return EVAL::OK; 312 case LE: // o 309 case LE: // operator <= 313 val.top() = (val1 <= val2) ? 1. : 0.; 310 val.top() = (val1 <= val2) ? 1. : 0.; 314 return EVAL::OK; 311 return EVAL::OK; 315 case LT: // o 312 case LT: // operator < 316 val.top() = (val1 < val2) ? 1. : 0.; 313 val.top() = (val1 < val2) ? 1. : 0.; 317 return EVAL::OK; 314 return EVAL::OK; 318 case PLUS: // o 315 case PLUS: // operator '+' 319 val.top() = val1 + val2; 316 val.top() = val1 + val2; 320 return EVAL::OK; 317 return EVAL::OK; 321 case MINUS: // o 318 case MINUS: // operator '-' 322 val.top() = val1 - val2; 319 val.top() = val1 - val2; 323 return EVAL::OK; 320 return EVAL::OK; 324 case MULT: // o 321 case MULT: // operator '*' 325 val.top() = val1 * val2; 322 val.top() = val1 * val2; 326 return EVAL::OK; 323 return EVAL::OK; 327 case DIV: // o 324 case DIV: // operator '/' 328 if (val2 == 0.0) return EVAL::ERROR_CALCUL 325 if (val2 == 0.0) return EVAL::ERROR_CALCULATION_ERROR; 329 val.top() = val1 / val2; 326 val.top() = val1 / val2; 330 return EVAL::OK; 327 return EVAL::OK; 331 case POW: // o 328 case POW: // operator '^' (or '**') 332 errno = 0; 329 errno = 0; 333 val.top() = std::pow(val1,val2); 330 val.top() = std::pow(val1,val2); 334 if (errno == 0) return EVAL::OK; 331 if (errno == 0) return EVAL::OK; 335 else return EVAL::ERROR_CALCULATION_ERROR; 332 else return EVAL::ERROR_CALCULATION_ERROR; 336 case UNARY_PLUS: 333 case UNARY_PLUS: // unary operator '+' 337 val.top() = val1 + val2; // val1 is z 334 val.top() = val1 + val2; // val1 is zero 338 return EVAL::OK; 335 return EVAL::OK; 339 case UNARY_MINUS: 336 case UNARY_MINUS: // unary operator '-' 340 val.top() = val1 - val2; // val1 is z 337 val.top() = val1 - val2; // val1 is zero 341 return EVAL::OK; 338 return EVAL::OK; 342 default: 339 default: 343 return EVAL::ERROR_CALCULATION_ERROR; 340 return EVAL::ERROR_CALCULATION_ERROR; 344 } 341 } 345 } 342 } 346 343 347 /********************************************* 344 /*********************************************************************** 348 * 345 * * 349 * Name: engine 346 * Name: engine Date: 28.09.00 * 350 * Author: Evgeni Chernyaev 347 * Author: Evgeni Chernyaev Revised: * 351 * 348 * * 352 * Function: Evaluates arithmetic expression. 349 * Function: Evaluates arithmetic expression. * 353 * 350 * * 354 * Parameters: 351 * Parameters: * 355 * begin - pointer to the character string 352 * begin - pointer to the character string with expression. * 356 * end - pointer to the end of the charac 353 * end - pointer to the end of the character string (it is needed * 357 * for recursive call of engine(), 354 * for recursive call of engine(), when there is no '\0'). * 358 * result - result of the evaluation. 355 * result - result of the evaluation. * 359 * endp - pointer to the character where t 356 * endp - pointer to the character where the evaluation stoped. * 360 * dictionary - dictionary of available vari 357 * dictionary - dictionary of available variables and functions. * 361 * 358 * * 362 ********************************************* 359 ***********************************************************************/ 363 static int engine(pchar begin, pchar end, doub 360 static int engine(pchar begin, pchar end, double & result, 364 pchar & endp, const dic_type & dictionar 361 pchar & endp, const dic_type & dictionary) 365 { 362 { 366 enum SyntaxTableEntry { 363 enum SyntaxTableEntry { 367 SyntaxError = 0, 364 SyntaxError = 0, 368 NumberVariableOrFunction = 1, 365 NumberVariableOrFunction = 1, 369 UnaryPlusOrMinus = 2, 366 UnaryPlusOrMinus = 2, 370 AnyOperator = 3 367 AnyOperator = 3 371 }; 368 }; 372 static const int SyntaxTable[19][19] = { 369 static const int SyntaxTable[19][19] = { 373 //E ( || && == != >= > <= < + - u+ u 370 //E ( || && == != >= > <= < + - u+ u- * / ^ ) V - current token 374 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2 371 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // E - previous 375 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2 372 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // ( token 376 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2 373 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // || 377 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2 374 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // && 378 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2 375 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // == 379 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2 376 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // != 380 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2 377 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // >= 381 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2 378 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // > 382 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2 379 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // <= 383 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2 380 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // < 384 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2 381 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // + 385 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2 382 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // - 386 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2 383 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // unary + 387 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2 384 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // unary - 388 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2 385 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // * 389 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2 386 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // / 390 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2 387 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // ^ 391 { 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 388 { 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0 }, // ) 392 { 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 389 { 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0 } // V = {.,N,C} 393 }; 390 }; 394 enum ActionTableEntry { 391 enum ActionTableEntry { 395 UnbalancedParentheses = -1, 392 UnbalancedParentheses = -1, 396 ExpressionCompleted = 0, 393 ExpressionCompleted = 0, 397 HigherPrecedenceOperator = 1, 394 HigherPrecedenceOperator = 1, 398 SamePrecedenceOperator = 2, 395 SamePrecedenceOperator = 2, 399 CloseProcessedParenthesesOrExpression = 3, 396 CloseProcessedParenthesesOrExpression = 3, 400 LowerPrecedenceOperator = 4 397 LowerPrecedenceOperator = 4 401 }; 398 }; 402 static const int ActionTable[17][18] = { 399 static const int ActionTable[17][18] = { 403 //E ( || && == != >= > <= < + - u+ u 400 //E ( || && == != >= > <= < + - u+ u- * / ^ ) - current operator 404 { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 401 { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,-1 }, // E - top operator 405 {-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 402 {-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3 }, // ( in stack 406 { 4, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 403 { 4, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4 }, // || 407 { 4, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 404 { 4, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4 }, // && 408 { 4, 1, 4, 4, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1 405 { 4, 1, 4, 4, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4 }, // == 409 { 4, 1, 4, 4, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1 406 { 4, 1, 4, 4, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4 }, // != 410 { 4, 1, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1 407 { 4, 1, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 4 }, // >= 411 { 4, 1, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1 408 { 4, 1, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 4 }, // > 412 { 4, 1, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1 409 { 4, 1, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 4 }, // <= 413 { 4, 1, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1 410 { 4, 1, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 4 }, // < 414 { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 1, 1 411 { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 1, 1, 1, 1, 1, 4 }, // + 415 { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 1, 1 412 { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 1, 1, 1, 1, 1, 4 }, // - 416 { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1 413 { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 4, 4, 1, 4 }, // unary + 417 { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1 414 { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 4, 4, 1, 4 }, // unary - 418 { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1 415 { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 2, 2, 1, 4 }, // * 419 { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1 416 { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 2, 2, 1, 4 }, // / 420 { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1 417 { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 4, 4, 4, 4 } // ^ 421 }; 418 }; 422 419 423 stack<int> op; // op 420 stack<int> op; // operator stack 424 stack<pchar> pos; // po 421 stack<pchar> pos; // position stack 425 stack<double> val; // va 422 stack<double> val; // value stack 426 double value; 423 double value; 427 pchar pointer = begin; 424 pchar pointer = begin; 428 int iWhat, iCur, iPrev = 0, iTop, 425 int iWhat, iCur, iPrev = 0, iTop, EVAL_STATUS; 429 char c; 426 char c; 430 427 431 op.push(0); pos.push(pointer); // pu 428 op.push(0); pos.push(pointer); // push EOL to the stack 432 SKIP_BLANKS; 429 SKIP_BLANKS; 433 if (c == '\0') { EVAL_EXIT( EVAL::WARNING_BL 430 if (c == '\0') { EVAL_EXIT( EVAL::WARNING_BLANK_STRING, begin ); } 434 for(;;pointer++) { 431 for(;;pointer++) { 435 432 436 // N E X T T O K E N 433 // N E X T T O K E N 437 434 438 c = (pointer > end) ? '\0' : *pointer; 435 c = (pointer > end) ? '\0' : *pointer; 439 if (isspace(c)) continue; // sk 436 if (isspace(c)) continue; // skip space, tab etc. 440 switch (c) { 437 switch (c) { 441 case '\0': iCur = ENDL; break; 438 case '\0': iCur = ENDL; break; 442 case '(': iCur = LBRA; break; 439 case '(': iCur = LBRA; break; 443 case '|': 440 case '|': 444 if (*(pointer+1) == '|') { 441 if (*(pointer+1) == '|') { 445 pointer++; iCur = OR; break; 442 pointer++; iCur = OR; break; 446 }else{ 443 }else{ 447 EVAL_EXIT( EVAL::ERROR_UNEXPECTED_SYMB 444 EVAL_EXIT( EVAL::ERROR_UNEXPECTED_SYMBOL, pointer ); 448 } 445 } 449 case '&': 446 case '&': 450 if (*(pointer+1) == '&') { 447 if (*(pointer+1) == '&') { 451 pointer++; iCur = AND; break; 448 pointer++; iCur = AND; break; 452 }else{ 449 }else{ 453 EVAL_EXIT( EVAL::ERROR_UNEXPECTED_SYMB 450 EVAL_EXIT( EVAL::ERROR_UNEXPECTED_SYMBOL, pointer ); 454 } 451 } 455 case '=': 452 case '=': 456 if (*(pointer+1) == '=') { 453 if (*(pointer+1) == '=') { 457 pointer++; iCur = EQ; break; 454 pointer++; iCur = EQ; break; 458 }else{ 455 }else{ 459 EVAL_EXIT( EVAL::ERROR_UNEXPECTED_SYMB 456 EVAL_EXIT( EVAL::ERROR_UNEXPECTED_SYMBOL, pointer ); 460 } 457 } 461 case '!': 458 case '!': 462 if (*(pointer+1) == '=') { 459 if (*(pointer+1) == '=') { 463 pointer++; iCur = NE; break; 460 pointer++; iCur = NE; break; 464 }else{ 461 }else{ 465 EVAL_EXIT( EVAL::ERROR_UNEXPECTED_SYMB 462 EVAL_EXIT( EVAL::ERROR_UNEXPECTED_SYMBOL, pointer ); 466 } 463 } 467 case '>': 464 case '>': 468 if (*(pointer+1) == '=') { pointer++; iC 465 if (*(pointer+1) == '=') { pointer++; iCur = GE; } else { iCur = GT; } 469 break; 466 break; 470 case '<': 467 case '<': 471 if (*(pointer+1) == '=') { pointer++; iC 468 if (*(pointer+1) == '=') { pointer++; iCur = LE; } else { iCur = LT; } 472 break; 469 break; 473 case '+': iCur = PLUS; break; 470 case '+': iCur = PLUS; break; 474 case '-': iCur = MINUS; break; 471 case '-': iCur = MINUS; break; 475 case '*': 472 case '*': 476 if (*(pointer+1) == '*') { pointer++; iC 473 if (*(pointer+1) == '*') { pointer++; iCur = POW; }else{ iCur = MULT; } 477 break; 474 break; 478 case '/': iCur = DIV; break; 475 case '/': iCur = DIV; break; 479 case '^': iCur = POW; break; 476 case '^': iCur = POW; break; 480 case ')': iCur = RBRA; break; 477 case ')': iCur = RBRA; break; 481 default: 478 default: 482 if (c == '.' || isalnum(c)) { 479 if (c == '.' || isalnum(c)) { 483 iCur = VALUE; break; 480 iCur = VALUE; break; 484 }else{ 481 }else{ 485 EVAL_EXIT( EVAL::ERROR_UNEXPECTED_SYMB 482 EVAL_EXIT( EVAL::ERROR_UNEXPECTED_SYMBOL, pointer ); 486 } 483 } 487 } 484 } 488 485 489 // S Y N T A X A N A L I S Y S 486 // S Y N T A X A N A L I S Y S 490 487 491 iWhat = SyntaxTable[iPrev][iCur]; 488 iWhat = SyntaxTable[iPrev][iCur]; 492 iPrev = iCur; 489 iPrev = iCur; 493 switch (iWhat) { 490 switch (iWhat) { 494 case 0: // syn 491 case 0: // syntax error 495 EVAL_EXIT( EVAL::ERROR_SYNTAX_ERROR, poi 492 EVAL_EXIT( EVAL::ERROR_SYNTAX_ERROR, pointer ); 496 case 1: // ope 493 case 1: // operand: number, variable, function 497 EVAL_STATUS = operand(pointer, end, valu 494 EVAL_STATUS = operand(pointer, end, value, pointer, dictionary); 498 if (EVAL_STATUS != EVAL::OK) { EVAL_EXIT 495 if (EVAL_STATUS != EVAL::OK) { EVAL_EXIT( EVAL_STATUS, pointer ); } 499 val.push(value); 496 val.push(value); 500 continue; 497 continue; 501 case 2: // una 498 case 2: // unary + or unary - 502 val.push(0.0); 499 val.push(0.0); 503 if (iCur == PLUS) iCur = UNARY_PLUS; 500 if (iCur == PLUS) iCur = UNARY_PLUS; 504 if (iCur == MINUS) iCur = UNARY_MINUS; 501 if (iCur == MINUS) iCur = UNARY_MINUS; 505 // Note that for syntax purposes, ordina 502 // Note that for syntax purposes, ordinary + or - are fine. 506 // Thus iPrev need not change when we en 503 // Thus iPrev need not change when we encounter a unary minus or plus. 507 case 3: default: // nex 504 case 3: default: // next operator 508 break; 505 break; 509 } 506 } 510 507 511 // N E X T O P E R A T O R 508 // N E X T O P E R A T O R 512 509 513 for(;;) { 510 for(;;) { 514 if (op.size() == 0) { EVAL_EXIT( EVAL::E 511 if (op.size() == 0) { EVAL_EXIT( EVAL::ERROR_SYNTAX_ERROR, pointer ); } 515 iTop = op.top(); 512 iTop = op.top(); 516 switch (ActionTable[iTop][iCur]) { 513 switch (ActionTable[iTop][iCur]) { 517 case -1: // sy 514 case -1: // syntax error 518 if (op.size() > 1) pointer = pos.top(); 515 if (op.size() > 1) pointer = pos.top(); 519 EVAL_EXIT( EVAL::ERROR_UNPAIRED_PARENTHESIS, 516 EVAL_EXIT( EVAL::ERROR_UNPAIRED_PARENTHESIS, pointer ); 520 case 0: // la 517 case 0: // last operation (assignment) 521 if (val.size() == 1) { 518 if (val.size() == 1) { 522 result = val.top(); 519 result = val.top(); 523 EVAL_EXIT( EVAL::OK, pointer ); 520 EVAL_EXIT( EVAL::OK, pointer ); 524 }else{ 521 }else{ 525 EVAL_EXIT( EVAL::ERROR_SYNTAX_ERROR, point 522 EVAL_EXIT( EVAL::ERROR_SYNTAX_ERROR, pointer ); 526 } 523 } 527 case 1: // pus 524 case 1: // push current operator in stack 528 op.push(iCur); pos.push(pointer); 525 op.push(iCur); pos.push(pointer); 529 break; 526 break; 530 case 2: // exe 527 case 2: // execute top operator 531 EVAL_STATUS = maker(iTop, val); // put 528 EVAL_STATUS = maker(iTop, val); // put current operator in stack 532 if (EVAL_STATUS != EVAL::OK) { 529 if (EVAL_STATUS != EVAL::OK) { 533 EVAL_EXIT( EVAL_STATUS, pos.top() ); 530 EVAL_EXIT( EVAL_STATUS, pos.top() ); 534 } 531 } 535 op.top() = iCur; pos.top() = pointer; 532 op.top() = iCur; pos.top() = pointer; 536 break; 533 break; 537 case 3: // del 534 case 3: // delete '(' from stack 538 op.pop(); pos.pop(); 535 op.pop(); pos.pop(); 539 break; 536 break; 540 case 4: default: // exe 537 case 4: default: // execute top operator and 541 EVAL_STATUS = maker(iTop, val); // del 538 EVAL_STATUS = maker(iTop, val); // delete it from stack 542 if (EVAL_STATUS != EVAL::OK) { // rep 539 if (EVAL_STATUS != EVAL::OK) { // repete with the same iCur 543 EVAL_EXIT( EVAL_STATUS, pos.top() ); 540 EVAL_EXIT( EVAL_STATUS, pos.top() ); 544 } 541 } 545 op.pop(); pos.pop(); 542 op.pop(); pos.pop(); 546 continue; 543 continue; 547 } 544 } 548 break; 545 break; 549 } 546 } 550 } 547 } 551 } 548 } 552 549 553 //-------------------------------------------- 550 //--------------------------------------------------------------------------- 554 static void setItem(const char * prefix, const 551 static void setItem(const char * prefix, const char * name, 555 const Item & item, Struct * s) { 552 const Item & item, Struct * s) { 556 553 557 if (name == 0 || *name == '\0') { 554 if (name == 0 || *name == '\0') { 558 s->theStatus = EVAL::ERROR_NOT_A_NAME; 555 s->theStatus = EVAL::ERROR_NOT_A_NAME; 559 return; 556 return; 560 } 557 } 561 558 562 // R E M O V E L E A D I N G A N D T 559 // R E M O V E L E A D I N G A N D T R A I L I N G S P A C E S 563 560 564 const char * pointer; int n; REMOVE_BLANKS; 561 const char * pointer; int n; REMOVE_BLANKS; 565 562 566 // C H E C K N A M E 563 // C H E C K N A M E 567 564 568 if (n == 0) { 565 if (n == 0) { 569 s->theStatus = EVAL::ERROR_NOT_A_NAME; 566 s->theStatus = EVAL::ERROR_NOT_A_NAME; 570 return; 567 return; 571 } 568 } 572 for(int i=0; i<n; i++) { 569 for(int i=0; i<n; i++) { 573 char c = *(pointer+i); 570 char c = *(pointer+i); 574 if (c != '_' && !isalnum(c)) { 571 if (c != '_' && !isalnum(c)) { 575 s->theStatus = EVAL::ERROR_NOT_A_NAME; 572 s->theStatus = EVAL::ERROR_NOT_A_NAME; 576 return; 573 return; 577 } 574 } 578 } 575 } 579 576 580 // A D D I T E M T O T H E D I C T 577 // A D D I T E M T O T H E D I C T I O N A R Y 581 578 582 string item_name = prefix + string(pointer,n 579 string item_name = prefix + string(pointer,n); 583 dic_type::iterator iter = (s->theDictionary) 580 dic_type::iterator iter = (s->theDictionary).find(item_name); 584 if (iter != (s->theDictionary).end()) { 581 if (iter != (s->theDictionary).end()) { 585 iter->second = item; 582 iter->second = item; 586 if (item_name == name) { 583 if (item_name == name) { 587 s->theStatus = EVAL::WARNING_EXISTING_VA 584 s->theStatus = EVAL::WARNING_EXISTING_VARIABLE; 588 }else{ 585 }else{ 589 s->theStatus = EVAL::WARNING_EXISTING_FU 586 s->theStatus = EVAL::WARNING_EXISTING_FUNCTION; 590 } 587 } 591 }else{ 588 }else{ 592 (s->theDictionary)[item_name] = item; 589 (s->theDictionary)[item_name] = item; 593 s->theStatus = EVAL::OK; 590 s->theStatus = EVAL::OK; 594 } 591 } 595 } 592 } 596 593 597 //-------------------------------------------- 594 //--------------------------------------------------------------------------- 598 namespace HepTool { 595 namespace HepTool { 599 596 600 //-------------------------------------------- 597 //--------------------------------------------------------------------------- 601 Evaluator::Evaluator() { 598 Evaluator::Evaluator() { 602 Struct * s = new Struct(); 599 Struct * s = new Struct(); 603 p = (void *) s; 600 p = (void *) s; 604 s->theExpression = 0; 601 s->theExpression = 0; 605 s->thePosition = 0; 602 s->thePosition = 0; 606 s->theStatus = OK; 603 s->theStatus = OK; 607 s->theResult = 0.0; 604 s->theResult = 0.0; 608 } 605 } 609 606 610 //-------------------------------------------- 607 //--------------------------------------------------------------------------- 611 Evaluator::~Evaluator() { 608 Evaluator::~Evaluator() { 612 delete (Struct *)(p); 609 delete (Struct *)(p); 613 } 610 } 614 611 615 //-------------------------------------------- 612 //--------------------------------------------------------------------------- 616 double Evaluator::evaluate(const char * expres 613 double Evaluator::evaluate(const char * expression) { 617 Struct * s = (Struct *)(p); 614 Struct * s = (Struct *)(p); 618 if (s->theExpression != 0) { delete[] s->the 615 if (s->theExpression != 0) { delete[] s->theExpression; } 619 s->theExpression = 0; 616 s->theExpression = 0; 620 s->thePosition = 0; 617 s->thePosition = 0; 621 s->theStatus = WARNING_BLANK_STRING; 618 s->theStatus = WARNING_BLANK_STRING; 622 s->theResult = 0.0; 619 s->theResult = 0.0; 623 if (expression != 0) { 620 if (expression != 0) { 624 s->theExpression = new char[strlen(express 621 s->theExpression = new char[strlen(expression)+1]; 625 strcpy(s->theExpression, expression); 622 strcpy(s->theExpression, expression); 626 s->theStatus = engine(s->theExpression, 623 s->theStatus = engine(s->theExpression, 627 s->theExpression+strlen(expression)-1, 624 s->theExpression+strlen(expression)-1, 628 s->theResult, 625 s->theResult, 629 s->thePosition, 626 s->thePosition, 630 s->theDictionary); 627 s->theDictionary); 631 } 628 } 632 return s->theResult; 629 return s->theResult; 633 } 630 } 634 631 635 //-------------------------------------------- 632 //--------------------------------------------------------------------------- 636 int Evaluator::status() const { 633 int Evaluator::status() const { 637 return ((Struct *)(p))->theStatus; 634 return ((Struct *)(p))->theStatus; 638 } 635 } 639 636 640 //-------------------------------------------- 637 //--------------------------------------------------------------------------- 641 int Evaluator::error_position() const { 638 int Evaluator::error_position() const { 642 return int(((Struct *)(p))->thePosition - (( << 639 return ((Struct *)(p))->thePosition - ((Struct *)(p))->theExpression; 643 } 640 } 644 641 645 //-------------------------------------------- 642 //--------------------------------------------------------------------------- 646 void Evaluator::print_error() const { 643 void Evaluator::print_error() const { 647 Struct * s = (Struct *) p; 644 Struct * s = (Struct *) p; 648 if(s->theStatus != OK) { 645 if(s->theStatus != OK) { 649 std::cerr << error_name() << std::endl; 646 std::cerr << error_name() << std::endl; 650 } 647 } 651 return; 648 return; 652 } 649 } 653 650 654 //-------------------------------------------- 651 //--------------------------------------------------------------------------- 655 std::string Evaluator::error_name() const 652 std::string Evaluator::error_name() const 656 { 653 { 657 char prefix[] = "Evaluator : "; 654 char prefix[] = "Evaluator : "; 658 std::ostringstream errn; 655 std::ostringstream errn; 659 Struct * s = (Struct *) p; 656 Struct * s = (Struct *) p; 660 switch (s->theStatus) { 657 switch (s->theStatus) { 661 case ERROR_NOT_A_NAME: 658 case ERROR_NOT_A_NAME: 662 errn << prefix << "invalid name"; 659 errn << prefix << "invalid name"; 663 break; 660 break; 664 case ERROR_SYNTAX_ERROR: 661 case ERROR_SYNTAX_ERROR: 665 errn << prefix << "syntax error"; 662 errn << prefix << "syntax error"; 666 break; 663 break; 667 case ERROR_UNPAIRED_PARENTHESIS: 664 case ERROR_UNPAIRED_PARENTHESIS: 668 errn << prefix << "unpaired parenthesis"; 665 errn << prefix << "unpaired parenthesis"; 669 break; 666 break; 670 case ERROR_UNEXPECTED_SYMBOL: 667 case ERROR_UNEXPECTED_SYMBOL: 671 errn << prefix << "unexpected symbol"; 668 errn << prefix << "unexpected symbol"; 672 break; 669 break; 673 case ERROR_UNKNOWN_VARIABLE: 670 case ERROR_UNKNOWN_VARIABLE: 674 errn << prefix << "unknown variable"; 671 errn << prefix << "unknown variable"; 675 break; 672 break; 676 case ERROR_UNKNOWN_FUNCTION: 673 case ERROR_UNKNOWN_FUNCTION: 677 errn << prefix << "unknown function"; 674 errn << prefix << "unknown function"; 678 break; 675 break; 679 case ERROR_EMPTY_PARAMETER: 676 case ERROR_EMPTY_PARAMETER: 680 errn << prefix << "empty parameter in func 677 errn << prefix << "empty parameter in function call"; 681 break; 678 break; 682 case ERROR_CALCULATION_ERROR: 679 case ERROR_CALCULATION_ERROR: 683 errn << prefix << "calculation error"; 680 errn << prefix << "calculation error"; 684 break; 681 break; 685 default: 682 default: 686 errn << " "; 683 errn << " "; 687 } 684 } 688 return errn.str(); 685 return errn.str(); 689 } 686 } 690 687 691 //-------------------------------------------- 688 //--------------------------------------------------------------------------- 692 void Evaluator::setVariable(const char * name, 689 void Evaluator::setVariable(const char * name, double value) 693 { setItem("", name, Item(value), (Struct *)p); 690 { setItem("", name, Item(value), (Struct *)p); } 694 691 695 void Evaluator::setVariable(const char * name, 692 void Evaluator::setVariable(const char * name, const char * expression) 696 { setItem("", name, Item(expression), (Struct 693 { setItem("", name, Item(expression), (Struct *)p); } 697 694 698 //-------------------------------------------- 695 //--------------------------------------------------------------------------- 699 // Fix non ISO C++ compliant cast from pointer 696 // Fix non ISO C++ compliant cast from pointer to function 700 // to void*, which is a pointer to an object 697 // to void*, which is a pointer to an object 701 void Evaluator::setFunction(const char * name, 698 void Evaluator::setFunction(const char * name, 702 double (*fun)()) 699 double (*fun)()) 703 { setItem("0", name, Item(reinterpret_cast<voi 700 { setItem("0", name, Item(reinterpret_cast<voidfuncptr>(fun)), (Struct *)p); } 704 701 705 void Evaluator::setFunction(const char * name, 702 void Evaluator::setFunction(const char * name, 706 double (*fun)(double)) 703 double (*fun)(double)) 707 { setItem("1", name, Item(reinterpret_cast<voi 704 { setItem("1", name, Item(reinterpret_cast<voidfuncptr>(fun)), (Struct *)p); } 708 705 709 void Evaluator::setFunction(const char * name, 706 void Evaluator::setFunction(const char * name, 710 double (*fun)(double,double)) 707 double (*fun)(double,double)) 711 { setItem("2", name, Item(reinterpret_cast<voi 708 { setItem("2", name, Item(reinterpret_cast<voidfuncptr>(fun)), (Struct *)p); } 712 709 713 void Evaluator::setFunction(const char * name, 710 void Evaluator::setFunction(const char * name, 714 double (*fun)(double,double,double)) 711 double (*fun)(double,double,double)) 715 { setItem("3", name, Item(reinterpret_cast<voi 712 { setItem("3", name, Item(reinterpret_cast<voidfuncptr>(fun)), (Struct *)p); } 716 713 717 void Evaluator::setFunction(const char * name, 714 void Evaluator::setFunction(const char * name, 718 double (*fun)(double,double,double,d 715 double (*fun)(double,double,double,double)) 719 { setItem("4", name, Item(reinterpret_cast<voi 716 { setItem("4", name, Item(reinterpret_cast<voidfuncptr>(fun)), (Struct *)p); } 720 717 721 void Evaluator::setFunction(const char * name, 718 void Evaluator::setFunction(const char * name, 722 double (*fun)(double,double,double,d 719 double (*fun)(double,double,double,double,double)) 723 { setItem("5", name, Item(reinterpret_cast<voi 720 { setItem("5", name, Item(reinterpret_cast<voidfuncptr>(fun)), (Struct *)p); } 724 721 725 //-------------------------------------------- 722 //--------------------------------------------------------------------------- 726 bool Evaluator::findVariable(const char * name 723 bool Evaluator::findVariable(const char * name) const { 727 if (name == 0 || *name == '\0') return false 724 if (name == 0 || *name == '\0') return false; 728 const char * pointer; int n; REMOVE_BLANKS; 725 const char * pointer; int n; REMOVE_BLANKS; 729 if (n == 0) return false; 726 if (n == 0) return false; 730 Struct * s = (Struct *)(p); 727 Struct * s = (Struct *)(p); 731 return 728 return 732 ((s->theDictionary).find(string(pointer,n) 729 ((s->theDictionary).find(string(pointer,n)) == (s->theDictionary).end()) ? 733 false : true; 730 false : true; 734 } 731 } 735 732 736 //-------------------------------------------- 733 //--------------------------------------------------------------------------- 737 bool Evaluator::findFunction(const char * name 734 bool Evaluator::findFunction(const char * name, int npar) const { 738 if (name == 0 || *name == '\0') return fa 735 if (name == 0 || *name == '\0') return false; 739 if (npar < 0 || npar > MAX_N_PAR) return fa 736 if (npar < 0 || npar > MAX_N_PAR) return false; 740 const char * pointer; int n; REMOVE_BLANKS; 737 const char * pointer; int n; REMOVE_BLANKS; 741 if (n == 0) return false; 738 if (n == 0) return false; 742 Struct * s = (Struct *)(p); 739 Struct * s = (Struct *)(p); 743 return ((s->theDictionary).find(sss[npar]+st 740 return ((s->theDictionary).find(sss[npar]+string(pointer,n)) == 744 (s->theDictionary).end()) ? false : true; 741 (s->theDictionary).end()) ? false : true; 745 } 742 } 746 743 747 //-------------------------------------------- 744 //--------------------------------------------------------------------------- 748 void Evaluator::removeVariable(const char * na 745 void Evaluator::removeVariable(const char * name) { 749 if (name == 0 || *name == '\0') return; 746 if (name == 0 || *name == '\0') return; 750 const char * pointer; int n; REMOVE_BLANKS; 747 const char * pointer; int n; REMOVE_BLANKS; 751 if (n == 0) return; 748 if (n == 0) return; 752 Struct * s = (Struct *)(p); 749 Struct * s = (Struct *)(p); 753 (s->theDictionary).erase(string(pointer,n)); 750 (s->theDictionary).erase(string(pointer,n)); 754 } 751 } 755 752 756 //-------------------------------------------- 753 //--------------------------------------------------------------------------- 757 void Evaluator::removeFunction(const char * na 754 void Evaluator::removeFunction(const char * name, int npar) { 758 if (name == 0 || *name == '\0') return; 755 if (name == 0 || *name == '\0') return; 759 if (npar < 0 || npar > MAX_N_PAR) return; 756 if (npar < 0 || npar > MAX_N_PAR) return; 760 const char * pointer; int n; REMOVE_BLANKS; 757 const char * pointer; int n; REMOVE_BLANKS; 761 if (n == 0) return; 758 if (n == 0) return; 762 Struct * s = (Struct *)(p); 759 Struct * s = (Struct *)(p); 763 (s->theDictionary).erase(sss[npar]+string(po 760 (s->theDictionary).erase(sss[npar]+string(pointer,n)); 764 } 761 } 765 762 766 //-------------------------------------------- 763 //--------------------------------------------------------------------------- 767 void Evaluator::clear() { 764 void Evaluator::clear() { 768 Struct * s = (Struct *) p; 765 Struct * s = (Struct *) p; 769 s->theDictionary.clear(); 766 s->theDictionary.clear(); 770 s->theExpression = 0; 767 s->theExpression = 0; 771 s->thePosition = 0; 768 s->thePosition = 0; 772 s->theStatus = OK; 769 s->theStatus = OK; 773 s->theResult = 0.0; 770 s->theResult = 0.0; 774 } 771 } 775 772 776 //-------------------------------------------- 773 //--------------------------------------------------------------------------- 777 } // namespace HepTool 774 } // namespace HepTool 778 775