10 #include "CLHEP/Evaluator/stack.icc"
11 #include "CLHEP/Evaluator/string.icc"
12 #include "CLHEP/Evaluator/hash_map.icc"
49 #define EVAL HepTool::Evaluator
51 #define REMOVE_BLANKS \
52 for(pointer=name;;pointer++) if (!isspace(*pointer)) break; \
53 for(n=strlen(pointer);n>0;n--) if (!isspace(*(pointer+n-1))) break
57 c = (pointer > end) ? '\0' : *pointer; \
58 if (!isspace(c)) break; \
61 #define EVAL_EXIT(STATUS,POSITION) endp = POSITION; return STATUS
66 enum {
ENDL,
LBRA,
OR,
AND,
EQ,
NE,
GE,
GT,
LE,
LT,
88 dic_type::const_iterator iter = dictionary.find(name);
89 if (iter == dictionary.end())
90 return EVAL::ERROR_UNKNOWN_VARIABLE;
91 Item item = iter->second;
98 pchar exp_end = exp_begin + strlen(exp_begin) - 1;
99 if (
engine(exp_begin, exp_end, result, exp_end, dictionary) == EVAL::OK)
102 return EVAL::ERROR_CALCULATION_ERROR;
105 return EVAL::ERROR_CALCULATION_ERROR;
109 static int function(
const string &
name, stack<double> & par,
127 int npar = par.size();
128 if (npar >
MAX_N_PAR)
return EVAL::ERROR_UNKNOWN_FUNCTION;
130 dic_type::const_iterator iter = dictionary.find(
sss[npar]+
name);
131 if (iter == dictionary.end())
return EVAL::ERROR_UNKNOWN_FUNCTION;
132 Item item = iter->second;
135 for(
int i=0; i<npar; i++) { pp[i] = par.top(); par.pop(); }
137 if (item.
function == 0)
return EVAL::ERROR_CALCULATION_ERROR;
146 result = ((double (*)(double,double))item.
function)(pp[1], pp[0]);
154 (pp[3],pp[2],pp[1],pp[0]);
157 result = ((double (*)(double,double,double,double,double))item.
function)
158 (pp[4],pp[3],pp[2],pp[1],pp[0]);
161 return (errno == 0) ? EVAL::OK : EVAL::ERROR_CALCULATION_ERROR;
184 pchar pointer = begin;
190 if (!isalpha(*pointer)) {
192 result = strtod(pointer, (
char **)(&pointer));
196 EVAL_EXIT( EVAL::ERROR_CALCULATION_ERROR, begin );
202 while(pointer <= end) {
204 if (c !=
'_' && !isalnum(c))
break;
217 EVAL_STATUS =
variable(name, result, dictionary);
218 EVAL_EXIT( EVAL_STATUS, (EVAL_STATUS == EVAL::OK) ? --pointer : begin);
226 pchar par_begin = pointer+1, par_end;
229 c = (pointer > end) ?
'\0' : *pointer;
232 EVAL_EXIT( EVAL::ERROR_UNPAIRED_PARENTHESIS, pos.top() );
234 pos.push(pointer);
break;
236 if (pos.size() == 1) {
238 EVAL_STATUS =
engine(par_begin, par_end, value, par_end, dictionary);
239 if (EVAL_STATUS == EVAL::WARNING_BLANK_STRING)
240 {
EVAL_EXIT( EVAL::ERROR_EMPTY_PARAMETER, --par_end ); }
241 if (EVAL_STATUS != EVAL::OK)
244 par_begin = pointer + 1;
248 if (pos.size() > 1) {
253 EVAL_STATUS =
engine(par_begin, par_end, value, par_end, dictionary);
254 switch (EVAL_STATUS) {
258 case EVAL::WARNING_BLANK_STRING:
260 {
EVAL_EXIT( EVAL::ERROR_EMPTY_PARAMETER, --par_end ); }
265 EVAL_STATUS =
function(
name, par,
result, dictionary);
266 EVAL_EXIT( EVAL_STATUS, (EVAL_STATUS == EVAL::OK) ? pointer : begin);
286 static int maker(
int op, stack<double> & val)
288 if (val.size() < 2)
return EVAL::ERROR_SYNTAX_ERROR;
289 double val2 = val.top(); val.pop();
290 double val1 = val.top();
293 val.top() = (val1 || val2) ? 1. : 0.;
296 val.top() = (val1 && val2) ? 1. : 0.;
299 val.top() = (val1 == val2) ? 1. : 0.;
302 val.top() = (val1 != val2) ? 1. : 0.;
305 val.top() = (val1 >= val2) ? 1. : 0.;
308 val.top() = (val1 > val2) ? 1. : 0.;
311 val.top() = (val1 <= val2) ? 1. : 0.;
314 val.top() = (val1 < val2) ? 1. : 0.;
317 val.top() = val1 + val2;
320 val.top() = val1 - val2;
323 val.top() = val1 * val2;
326 if (val2 == 0.0)
return EVAL::ERROR_CALCULATION_ERROR;
327 val.top() = val1 / val2;
331 val.top() = std::pow(val1,val2);
332 if (errno == 0)
return EVAL::OK;
333 else return EVAL::ERROR_CALCULATION_ERROR;
335 val.top() = val1 + val2;
338 val.top() = val1 - val2;
341 return EVAL::ERROR_CALCULATION_ERROR;
364 enum SyntaxTableEntry {
366 NumberVariableOrFunction = 1,
367 UnaryPlusOrMinus = 2,
370 static const int SyntaxTable[19][19] = {
372 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 },
373 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 },
374 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 },
375 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 },
376 { 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, 0, 0, 0, 0, 1 },
378 { 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, 0, 0, 0, 0, 1 },
380 { 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, 0, 0, 0, 0, 1 },
382 { 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, 0, 0, 0, 0, 1 },
384 { 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, 0, 0, 0, 0, 1 },
386 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 },
387 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 },
388 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 },
389 { 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0 },
390 { 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0 }
392 enum ActionTableEntry {
393 UnbalancedParentheses = -1,
394 ExpressionCompleted = 0,
395 HigherPrecedenceOperator = 1,
396 SamePrecedenceOperator = 2,
397 CloseProcessedParenthesesOrExpression = 3,
398 LowerPrecedenceOperator = 4
400 static const int ActionTable[17][18] = {
402 { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,-1 },
403 {-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3 },
404 { 4, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4 },
405 { 4, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4 },
406 { 4, 1, 4, 4, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4 },
407 { 4, 1, 4, 4, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4 },
408 { 4, 1, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 4 },
409 { 4, 1, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 4 },
410 { 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, 1, 1, 1, 4 },
412 { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 1, 1, 1, 1, 1, 4 },
413 { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 1, 1, 1, 1, 1, 4 },
414 { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 4, 4, 1, 4 },
415 { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 4, 4, 1, 4 },
416 { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 2, 2, 1, 4 },
417 { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 2, 2, 1, 4 },
418 { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 4, 4, 4, 4 }
425 pchar pointer = begin;
426 int iWhat, iCur, iPrev = 0, iTop, EVAL_STATUS;
429 op.push(0); pos.push(pointer);
431 if (c ==
'\0') {
EVAL_EXIT( EVAL::WARNING_BLANK_STRING, begin ); }
436 c = (pointer > end) ?
'\0' : *pointer;
437 if (isspace(c))
continue;
439 case '\0': iCur =
ENDL;
break;
440 case '(': iCur =
LBRA;
break;
442 if (*(pointer+1) ==
'|') {
443 pointer++; iCur =
OR;
break;
445 EVAL_EXIT( EVAL::ERROR_UNEXPECTED_SYMBOL, pointer );
448 if (*(pointer+1) ==
'&') {
449 pointer++; iCur =
AND;
break;
451 EVAL_EXIT( EVAL::ERROR_UNEXPECTED_SYMBOL, pointer );
454 if (*(pointer+1) ==
'=') {
455 pointer++; iCur =
EQ;
break;
457 EVAL_EXIT( EVAL::ERROR_UNEXPECTED_SYMBOL, pointer );
460 if (*(pointer+1) ==
'=') {
461 pointer++; iCur =
NE;
break;
463 EVAL_EXIT( EVAL::ERROR_UNEXPECTED_SYMBOL, pointer );
466 if (*(pointer+1) ==
'=') { pointer++; iCur =
GE; }
else { iCur =
GT; }
469 if (*(pointer+1) ==
'=') { pointer++; iCur =
LE; }
else { iCur =
LT; }
471 case '+': iCur =
PLUS;
break;
472 case '-': iCur =
MINUS;
break;
474 if (*(pointer+1) ==
'*') { pointer++; iCur =
POW; }
else{ iCur =
MULT; }
476 case '/': iCur =
DIV;
break;
477 case '^': iCur =
POW;
break;
478 case ')': iCur =
RBRA;
break;
480 if (c ==
'.' || isalnum(c)) {
483 EVAL_EXIT( EVAL::ERROR_UNEXPECTED_SYMBOL, pointer );
489 iWhat = SyntaxTable[iPrev][iCur];
493 EVAL_EXIT( EVAL::ERROR_SYNTAX_ERROR, pointer );
495 EVAL_STATUS =
operand(pointer, end, value, pointer, dictionary);
496 if (EVAL_STATUS != EVAL::OK) {
EVAL_EXIT( EVAL_STATUS, pointer ); }
512 if (op.size() == 0) {
EVAL_EXIT( EVAL::ERROR_SYNTAX_ERROR, pointer ); }
514 switch (ActionTable[iTop][iCur]) {
516 if (op.size() > 1) pointer = pos.top();
517 EVAL_EXIT( EVAL::ERROR_UNPAIRED_PARENTHESIS, pointer );
519 if (val.size() == 1) {
523 EVAL_EXIT( EVAL::ERROR_SYNTAX_ERROR, pointer );
526 op.push(iCur); pos.push(pointer);
529 EVAL_STATUS =
maker(iTop, val);
530 if (EVAL_STATUS != EVAL::OK) {
533 op.top() = iCur; pos.top() = pointer;
539 EVAL_STATUS =
maker(iTop, val);
540 if (EVAL_STATUS != EVAL::OK) {
555 if (name == 0 || *name ==
'\0') {
570 for(
int i=0; i<
n; i++) {
571 char c = *(pointer+i);
572 if (c !=
'_' && !isalnum(c)) {
580 string item_name = prefix + string(pointer,n);
581 dic_type::iterator iter = (s->
theDictionary).find(item_name);
584 if (item_name == name) {
585 s->
theStatus = EVAL::WARNING_EXISTING_VARIABLE;
587 s->
theStatus = EVAL::WARNING_EXISTING_FUNCTION;
621 if (expression != 0) {
635 return ((
Struct *)(
p))->theStatus;
640 return ((
Struct *)(
p))->thePosition - ((
Struct *)(
p))->theExpression;
655 char prefix[] =
"Evaluator : ";
656 std::ostringstream errn;
660 errn << prefix <<
"invalid name";
663 errn << prefix <<
"syntax error";
666 errn << prefix <<
"unpaired parenthesis";
669 errn << prefix <<
"unexpected symbol";
672 errn << prefix <<
"unknown variable";
675 errn << prefix <<
"unknown function";
678 errn << prefix <<
"empty parameter in function call";
681 errn << prefix <<
"calculation error";
704 double (*fun)(
double))
708 double (*fun)(
double,
double))
712 double (*fun)(
double,
double,
double))
716 double (*fun)(
double,
double,
double,
double))
720 double (*fun)(
double,
double,
double,
double,
double))
725 if (name == 0 || *name ==
'\0')
return false;
727 if (n == 0)
return false;
736 if (name == 0 || *name ==
'\0')
return false;
737 if (npar < 0 || npar >
MAX_N_PAR)
return false;
739 if (n == 0)
return false;
747 if (name == 0 || *name ==
'\0')
return;
756 if (name == 0 || *name ==
'\0')
return;
757 if (npar < 0 || npar >
MAX_N_PAR)
return;
static const G4double pos
hash_map< string, Item > dic_type
static int engine(pchar, pchar, double &, pchar &, const dic_type &)
static const char sss[MAX_N_PAR+2]
static int maker(int op, stack< double > &val)
const XML_Char int const XML_Char * value
#define EVAL_EXIT(STATUS, POSITION)
G4double G4ParticleHPJENDLHEData::G4double result
static int variable(const string &name, double &result, const dic_type &dictionary)
static void setItem(const char *prefix, const char *name, const Item &item, Struct *s)
typedef void(XMLCALL *XML_ElementDeclHandler)(void *userData
static int operand(pchar begin, pchar end, double &result, pchar &endp, const dic_type &dictionary)