source: Sophya/trunk/SophyaLib/SysTools/cexpre.cc@ 4079

Last change on this file since 4079 was 4063, checked in by ansari, 13 years ago

Introduction de la classe interface CE_VarListInterface et modifs classe CExpressionEvaluator pour permettre l'inclusion de variables nommees dans les expressions traitees par CExpressionEvaluator, adaptation de la classe Commander afin que les variables de l'interpreteur soit visible par l'evaluateur CExpressionEvaluator, Reza 27/04/2012

File size: 18.9 KB
RevLine 
[2510]1#include <stdlib.h>
2#include <stdio.h>
3#include <ctype.h>
4#include <string.h>
[2615]5#include "sopnamsp.h"
[2510]6#include "cexpre.h"
7#include <stack>
8#include <math.h>
[2593]9#include "srandgen.h"
[2510]10
11namespace SOPHYA {
12
13long CExprBase::totnexp_create = 0;
14long CExprBase::totnexp_delete = 0;
15CExprBase::CExprBase()
16{
17 totnexp_create++;
18 // cout << "CExprBase::CExprBase()-Creation " << hex << this << dec << endl;
19}
20
21CExprBase::~CExprBase()
22{
23 totnexp_delete++;
24 // cout << "CExprBase::~CExprBase() " << hex << this << dec << endl;
25}
26
27void CExprBase::CheckThrow(const char * msg) const
28{
29 string errmsg;
30 bool ok = CheckE(errmsg);
31 if (ok) return;
32 else {
33 errmsg += msg;
34 throw CExprException(errmsg);
35 }
36}
37
38//---------------------------------------------------------
[2804]39/*!
40 \internal
41 \ingroup SysTools
42 \brief Class representing numbers for expression evaluation
43 \sa CExpressionEvaluator
44*/
[2510]45class CE_NumberExp : public CExprBase {
46public:
[4063]47 CE_NumberExp(double v) { _val = v; _pval=&_val; }
48 CE_NumberExp(double* pv) { _pval=pv; _val = *_pval; }
[2510]49 CE_NumberExp(string const & s);
50 virtual ~CE_NumberExp() {}
[4063]51 virtual double Evaluate() const { return (*_pval); }
52 virtual void Print(ostream& os) const { os << (*_pval); }
[2510]53protected:
54 double _val;
[4063]55 double* _pval;
[2510]56};
57
58CE_NumberExp::CE_NumberExp(string const & s)
59{
[4063]60 _pval=&_val;
[2510]61 size_t l = s.length();
62 if (l < 1) {
63 string errmsg = "CE_NumberExp::CE_NumberExp() Empty expression";
64 throw CExprException(errmsg);
65 }
66 if (s == "Pi") _val = M_PI;
67 else if (s == "E") _val = M_E;
68 else {
[4063]69 string errmsg = "CE_NumberExp::CE_NumberExp() Bad numerical constant or unknown variable: ";
[2510]70 errmsg += s;
71
[2518]72 char* lcc;
73 _val = strtod(s.c_str(), &lcc);
74 if (*lcc != '\0') throw CExprException(errmsg);
[2510]75 }
76}
77
[2550]78//---------------------------------------------------------
79//----------- Expression changement de signe -------------
[2598]80/*!
81 \internal
82 \ingroup SysTools
83 \brief Class for handling change sign expression (-x)
84 \sa CExpressionEvaluator
85*/
[2550]86class CE_ChsExp : public CExprBase {
87public:
88 explicit CE_ChsExp(CExprBase * e) { _e = e; }
89 virtual ~CE_ChsExp() { if (_e) delete _e; }
90 virtual double Evaluate() const { return -_e->Evaluate(); }
91 virtual bool CheckE(string& errmsg) const { if (_e) return true; else return false; }
92 virtual void Print(ostream& os) const { os << "-( "; _e->Print(os); os << " )"; }
93 protected:
94 CExprBase * _e;
95};
[2510]96
97//---------------------------------------------------------
[2598]98/*!
99 \internal
100 \ingroup SysTools
101 \brief Base class for binary operations on expressions
102 \sa CExpressionEvaluator
103*/
[2510]104class CE_BinExp : public CExprBase {
105public:
106 explicit CE_BinExp(char op, int prior);
107 virtual ~CE_BinExp() { if (_e1) delete _e1; if (_e2) delete _e2; }
108 inline void SetE1(CExprBase * e) { _e1 = e; }
109 inline void SetE2(CExprBase * e) { _e2 = e; }
110 virtual bool CheckE(string& errmsg) const;
111 virtual void Print(ostream& os) const;
112 inline char BOpC() const { return _bop; }
113 inline int Priority() const { return _priority; }
114 protected:
115 CExprBase * _e1;
116 CExprBase * _e2;
117 char _bop; // Caractere identificateur d'operation (+,-,*,/ ...)
118 int _priority; // Niveau de priorite: 1= +,- 2: *,/ 3: ^...
119};
120
121CE_BinExp::CE_BinExp(char op, int prior)
122{
123 _e1 = NULL; _e2 = NULL;
124 _bop = op;
125 _priority = prior;
126}
127
128bool CE_BinExp::CheckE(string& errmsg) const
129{
130 if ((_e1 == NULL) || (_e2 == NULL)) {
131 errmsg += "CE_BinExp::CheckE: Binary expression-missing argument ";
132 return false;
133 }
134 return true;
135}
136
137void CE_BinExp::Print(ostream& os) const
138{
139 os << "(" << (*_e1) << _bop << (*_e2) << ")" ;
140}
141
142//---------------------------------------------------------
[2598]143/*!
144 \internal
145 \ingroup SysTools
146 \brief Addition of two CExprBase (binary operation : x+y)
147 \sa CExpressionEvaluator
148*/
[2510]149class CE_AddExp : public CE_BinExp {
150public:
151 CE_AddExp() : CE_BinExp('+',1) {}
152 virtual double Evaluate() const { CheckThrow("CE_AddExp::Evaluate"); return _e1->Evaluate()+_e2->Evaluate();
153 }
154};
[2598]155/*!
156 \internal
157 \ingroup SysTools
158 \brief Multiplication of two CExprBase (binary operation : x*y)
159 \sa CExpressionEvaluator
160*/
[2510]161class CE_MulExp : public CE_BinExp {
162public:
163 CE_MulExp() : CE_BinExp('*',2) {}
164 virtual double Evaluate() const { CheckThrow("CE_MulExp::Evaluate"); return _e1->Evaluate()*_e2->Evaluate(); }
165};
[2598]166/*!
167 \internal
168 \ingroup SysTools
169 \brief Subtraction of two CExprBase (binary operation : x-y)
170 \sa CExpressionEvaluator
171*/
[2510]172class CE_SubExp : public CE_BinExp {
173public:
174 CE_SubExp() : CE_BinExp('-',1) {}
175 virtual double Evaluate() const { CheckThrow("CE_SubExp::Evaluate"); return _e1->Evaluate()-_e2->Evaluate(); }
176};
[2598]177/*!
178 \internal
179 \ingroup SysTools
180 \brief Division of two CExprBase (binary operation : x/y)
181 \sa CExpressionEvaluator
182*/
[2510]183class CE_DivExp : public CE_BinExp {
184public:
185 CE_DivExp() : CE_BinExp('/',2) {}
186 virtual double Evaluate() const { CheckThrow("CE_DivExp::Evaluate"); return _e1->Evaluate()/_e2->Evaluate(); }
187};
188
189//---------------------------------------------------------
190typedef double (* f0exp) ();
191typedef double (* f1exp) (double x);
192typedef double (* f2exp) (double x, double y);
193typedef double (* f3exp) (double x, double y, double z);
194
195//---------------------------------------------------------
196#define FMXARG 3
[2598]197/*!
198 \internal
199 \ingroup SysTools
200 \brief Function evaluation on other expression in the form f(), f(x), f(x,y), f(x,y,z)
201 \sa CExpressionEvaluator
202*/
[2510]203class CE_FuncExp : public CExprBase {
204public:
205 CE_FuncExp(string const & func);
206 virtual ~CE_FuncExp();
207 virtual double Evaluate() const ;
208 inline void AddArg(CExprBase * e);
[2593]209 inline int GetMaxNArg() const { return _maxne; }
[2510]210 virtual bool CheckE(string& errmsg) const;
211 virtual void Print(ostream& os) const;
212protected:
213 f0exp _f0;
214 f1exp _f1;
215 f2exp _f2;
216 f3exp _f3;
217 int _ne, _maxne;
218 CExprBase * _e[FMXARG];
219 string _fname;
220};
221
[2593]222// Les fonctions de generation de nombre aleatoire
[2598]223static double _CE_rand01() { return drand01(); }
224static double _CE_randpm1() { return drandpm1(); }
[3617]225static double _CE_gaurand() { return GaussianRand(1.,0.); }
[2510]226//---------------------------------------------------------
227CE_FuncExp::CE_FuncExp(string const & func)
228{
229 _ne = 0; _maxne = -1;
230 for(int k=0; k<FMXARG; k++) _e[k] = NULL;
231 _f0 = NULL;
232 _f1 = NULL;
233 _f2 = NULL;
234 _f3 = NULL;
235 if (func == "sin") _f1 = sin;
236 else if (func == "cos") _f1 = cos;
237 else if (func == "tan") _f1 = tan;
238 else if (func == "asin") _f1 = asin;
239 else if (func == "acos") _f1 = acos;
240 else if (func == "atan") _f1 = atan;
241 else if (func == "atan2") _f2 = atan2;
[2518]242 else if (func == "sqrt") _f1 = sqrt;
243 else if (func == "fabs") _f1 = fabs;
244 else if (func == "floor") _f1 = floor;
[2510]245 else if (func == "exp") _f1 = exp;
246 else if (func == "log") _f1 = log;
247 else if (func == "log10") _f1 = log10;
248 else if (func == "pow") _f2 = pow;
[2518]249 else if (func == "hypot") _f2 = hypot;
250 else if (func == "sinh") _f1 = sinh;
251 else if (func == "cosh") _f1 = cosh;
252 else if (func == "tanh") _f1 = tanh;
[2593]253// Les fonctions aleatoires declaree plus haut
254 else if (func == "rand01") _f0 = _CE_rand01;
255 else if (func == "randpm1") _f0 = _CE_randpm1;
256 else if (func == "gaurand") _f0 = _CE_gaurand;
[2510]257 else {
258 string errmsg = "CE_FuncExp::CE_FuncExp() - Uknown function " ;
259 errmsg += func;
260 throw CExprException(errmsg);
261 }
262 if (_f0) _maxne = 0;
263 else if (_f1) _maxne = 1;
264 else if (_f2) _maxne = 2;
265 else if (_f3) _maxne = 3;
266 _fname = func;
267}
268
269
270CE_FuncExp::~CE_FuncExp()
271{
272for(int k=0; k<FMXARG; k++) if (_e[k]) delete _e[k];
273}
274
275void CE_FuncExp::AddArg(CExprBase * e)
276{
277 if ((e != NULL) && (_ne < _maxne)) { _e[_ne] = e; _ne++; }
278 else throw CExprException("CE_FuncExp::AddArg() e=NULL or too many arguments ");
279}
280
281double CE_FuncExp::Evaluate() const
282{
[2593]283 if ((_ne != _maxne) || (_maxne < 0) ) {
[2510]284 throw CExprException("CE_FuncExp::Evaluate() - Wrong argument number ");
285 }
[2593]286 if (_ne == 0) return _f0();
287 else if (_ne == 1) return _f1(_e[0]->Evaluate());
[2510]288 else if (_ne == 2) return _f2(_e[0]->Evaluate(), _e[1]->Evaluate());
289 else if (_ne == 3) return _f3(_e[0]->Evaluate(), _e[1]->Evaluate(),
290 _e[2]->Evaluate());
291 else return 0.;
292}
293
294bool CE_FuncExp::CheckE(string& errmsg) const
295{
296 if ((_ne != _maxne) || (_maxne < 0) ) {
297 char buff[128];
298 sprintf(buff, "CE_FuncExp::CheckE() %s - Wrong argument number - ne=%d maxne=%d ",
299 _fname.c_str(), _ne, _maxne);
300 errmsg += buff;
301 return false;
302 }
303 return true;
304}
305
306void CE_FuncExp::Print(ostream& os) const
307{
308 if ((_ne != _maxne) || (_maxne < 1) )
309 os << _fname << "(ArgError)" ;
310 else {
311 if (_ne == 1) os << _fname << "(" << *(_e[0]) << ")";
312 else if (_ne == 2) os << _fname << "(" << *(_e[0]) << "," << *(_e[1]) << ")";
313 else if (_ne == 3) os << _fname << "(" << *(_e[0])
314 << "," << *(_e[1]) << "," << *(_e[2]) << ")";
315 }
316}
317
318//---------------------------------------------------------
[2598]319/*!
320 \class CExpressionEvaluator
321 \ingroup SysTools
322 \brief Class for evaluation of arithmetic expressions with C-like syntax.
323
324 This classes can handle the parsing of c-like arithmetic
325 expressions containing numerical constants, the four
326 basic operations (addition +, subtraction -, multiplication *,
327 division /) and functions.
328 The numerical constants are also defined <tt> (Pi = M_PI E = M_E) </tt>.
329 The following functions from the standard math library and
330 random generators are available:
331
332 - sqrt fabs floor hypot
333 - exp log log10 pow
334 - sin cos tan asin acos atan atan2
335 - sinh cosh tanh
336 - rand01() : Flat random number generator in the range [0 1]
337 - randpm1() : Flat random number generator in the range [-1 1]
338 - gaurand() : Gaussian random number generator (m=0, sigma=1)
339
340 Usage example :
341 \code
342 #include "cexpre.h"
343 ...
344 string es = "4.+3*(cos(Pi/8.)+1.5)";
345 CExpressionEvaluator e(es);
346 cout << " Expression: " << e << " = " << e.Evaluate() << endl;
347 \endcode
348
349 Output : \n
350 <tt> Expression: (4+(3*(cos((3.14159/8))+1.5))) = 11.2716 </tt>
351*/
352
353/*!
[4063]354 Parse the character string \c exp and builds an expression. Uses the given list of variables
355 \c varlist if a valid pointer is provided. Can throw CExprException exception.
[2598]356*/
[4063]357CExpressionEvaluator::CExpressionEvaluator(const char* exp, CE_VarListInterface* varlist)
[2510]358{
359 _exp = NULL;
[4063]360 _varlist = varlist;
[2510]361 size_t off=0,stop=0;
362 string fname = "";
363 string errmsg;
[4063]364 string sexp=exp;
365 _exp= ParseString(0,fname,sexp,off,stop,errmsg);
366 if (_exp == NULL) throw CExprException(errmsg);
367}
368
369/*!
370 Parse the string \c sex and builds an expression. Uses the given list of variables
371 \c varlist if a valid pointer is provided. Can throw CExprException exception.
372*/
373CExpressionEvaluator::CExpressionEvaluator(string const & sex, CE_VarListInterface* varlist)
374{
375 _exp = NULL;
376 _varlist = varlist;
377 size_t off=0,stop=0;
378 string fname = "";
379 string errmsg;
[2510]380 _exp= ParseString(0,fname,sex,off,stop,errmsg);
381 if (_exp == NULL) throw CExprException(errmsg);
382}
383
384CExpressionEvaluator::~CExpressionEvaluator()
385{
386 if (_exp) delete _exp;
387}
388
389double CExpressionEvaluator::Evaluate() const
390{
391 if (_exp) return _exp->Evaluate();
392 else return 0.;
393}
394
395void CExpressionEvaluator::Print(ostream& os) const
396{
397 if (_exp) _exp->Print(os);
398 else os << "CExpressionEvaluator ???";
399}
400
401// cette fonction rearrange le stack des operations binaires en attente
[2598]402static CExprBase* Arrange_CE_BinExpStack(stack<CE_BinExp* >& sbx, CExprBase* cex, CE_BinExp* nbx)
[2510]403{
404 while ( !sbx.empty() && (nbx->Priority() <= sbx.top()->Priority()) ) {
405 sbx.top()->SetE2(cex);
406 cex = sbx.top(); sbx.pop();
407 }
408 nbx->SetE1(cex);
409 sbx.push(nbx);
410 return NULL;
411}
412
413// cette fonction rearrange le stack des operations binaires en attente
[2598]414static CExprBase* Arrange_CE_BinExpStack(stack<CE_BinExp* >& sbx, CExprBase* cex)
[2510]415{
416 if (sbx.empty()) return cex;
417 while ( !sbx.empty() ) {
418 sbx.top()->SetE2(cex);
419 cex = sbx.top(); sbx.pop();
420 }
421 return cex;
422}
423
[4063]424CExprBase* CExpressionEvaluator::VarNameOrNumber(string const & s)
425{
426 if (_varlist==NULL) return new CE_NumberExp(s);
427 double* pv=_varlist->GetVarPointer(s);
428 if (pv!=NULL) return new CE_NumberExp(pv);
429 return new CE_NumberExp(s);
430}
[2510]431
432CExprBase* CExpressionEvaluator::ParseString(int extype, string fname, string const & sex,
433 size_t off, size_t& stop, string& errmsg)
434{
435 size_t len = sex.length();
436 if (len < 1) {
437 string errmsg = "CExpressionEvaluator::ParseString() Empty expression";
438 throw CExprException(errmsg);
439 }
[2515]440 errmsg = "";
[2510]441 CExprBase* rx = NULL; // Expression resultat
442 stack< CE_BinExp* > sbx; // Stack des expressions binaires
443 CE_FuncExp* fx = NULL; // Expression fonction
444 CExprBase* cx = NULL; // Element d'expression (courante)
445
446 if (extype == 2) fx = new CE_FuncExp(fname);
447
448 size_t p=0, q=0;
449 char lastopc=0, opc=0; // Last/current operation sign (+,-,*,/,...)
[2520]450 int osn = 0;
[2510]451 bool finok = false;
452 bool fgcont = true;
453 bool checkok = true;
[2593]454 bool apperrmsg = true;
[2510]455 // cout << " DBG-ParseString off= " << off << " sex[off]= " << sex[off]
456 // << " extype= " << extype << endl;
457 p = stop = off;
458 while ((p < len) && (fgcont) && (checkok) ) {
[2593]459 // cout << " DBG-2-ParseString p=" << p << " q=" << q << endl;
[2510]460
461 cx = NULL;
[2593]462 // ------------------------------- Bretelle ------
463 // Il faut sauter les signes +/- qui se trouverait dans les
464 // exposants des nombres xxxe-yy xxxe+y : 0.4e-2 ...
465 // Les qques lignes sont une bretelle qui saute ces signes +/- (Reza, Aout 2004)
466 // On verifie d'abord s'il y a un nombre valide au debut de la positions courante
467 char* lcc;
468 size_t pfn=0,psn;
469 bool numberok = false;
470 strtod(sex.c_str()+p, &lcc);
471 if (lcc != sex.c_str()+p) { // Expression valide de double au debut
472 numberok = true; // de la position courante
473 pfn = lcc-sex.c_str();
474 }
475 // On cherche le 1er signe d'operateur - apres le nombre de debut
[2510]476 q = sex.find_first_of("+-*/(),",p);
[2593]477
478 while ( numberok && (q < len) && (q < pfn) && (q > p) &&
479 ((sex[q] == '+') || (sex[q] == '-')) ) {
480 psn = q+1;
481 if (psn < len) q = sex.find_first_of("+-*/(),",psn);
482 else q = len+1;
483 }
484 //---- Fin de la Bretelle ---- pour sauter les signes +/- de l'exposant des nombres
485
[2510]486 if (q < len) { // operateur trouve
487 opc = sex[q]; // signe operateur courant
488 switch (opc) {
489 case '(' :
490 if (q == p) {
491 string fname = "";
492 cx = ParseString(1, fname, sex, q+1, stop, errmsg);
493 }
494 else cx = ParseString(2, sex.substr(p,q-p), sex, q+1, stop, errmsg);
[2593]495 if (!cx) { checkok = false; p = stop+1; apperrmsg = false; }
[2510]496 else {
[2550]497 if (osn == 1) {
498 if (sex[p-osn] == '-') cx = new CE_ChsExp(cx);
499 }
500 if (osn > 1) {
[2510]501 checkok = false; p = stop+1; fgcont = false;
502 delete cx;
[2550]503 errmsg = "CExpressionEvaluator::ParseString()/ Syntax Error - multiple chs (+/-) (AA)";
504 }
505 else if (rx) {
506 checkok = false; p = stop+1; fgcont = false;
507 delete cx;
[2510]508 errmsg = "CExpressionEvaluator::ParseString()/ Syntax Error - rx&&cx (A)";
509 }
510 else {
511 if (stop == len-1) {
512 rx = Arrange_CE_BinExpStack(sbx, cx);
513 finok = true;
514 }
515 else rx = cx;
[2520]516 p = stop+1; osn = 0; lastopc = opc;
[2510]517 }
518 }
519 break;
520
521 case ')' :
522 case ',' :
523 if (extype == 0) {
524 checkok = false; p = q; fgcont = false;
525 errmsg = "CExpressionEvaluator::ParseString() Unexpected ) or ,";
526 }
527 if ( (extype == 1) && (opc == ',')) {
528 checkok = false; p = q; fgcont = false;
529 errmsg = "CExpressionEvaluator::ParseString() Unexpected ,";
530 }
531 if ((q > p) && (rx)) {
532 checkok = false; p = q; fgcont = false;
533 errmsg = "CExpressionEvaluator::ParseString()/ Syntax Error - rx&&cx (B)";
534 }
[4063]535 if (q > p) cx = VarNameOrNumber(sex.substr(p-osn,q-p+osn));
[2510]536 else cx = rx;
537
[2593]538 if (!cx && ( !fx || ( opc != ')' ) ||
539 ( (fx && (fx->GetMaxNArg() > 0) && (opc == ')' ) ) ) ) ) {
[2510]540 checkok = false; p = q; fgcont = false;
541 errmsg = "CExpressionEvaluator::ParseString()/ Syntax Error - farg=NULL (BB)";
542 }
543 else {
[2593]544 if (cx) { rx = Arrange_CE_BinExpStack(sbx, cx);
545 if (extype == 2) {
546 // cout << " DBG-ParseString-AddArg " << *(cx) << endl;
547 fx->AddArg(rx); rx = NULL;
548 }
549 }
[2510]550 if (opc == ')') { // Signe de fin de traitement d'une portion d'expression
551 if (extype == 2) { rx = fx; fx = NULL; }
[2520]552 stop = q; osn = 0; lastopc = opc;
[2510]553 fgcont = false;
554 finok = true;
555 }
556 else {
557 if (q == (len-1)) finok = true;
[2520]558 p = q+1; osn = 0; lastopc = opc;
[2510]559 }
560 }
561 break;
562
563 case '+' :
564 case '-' :
565 case '*' :
566 case '/' :
[2520]567 if (!( ((opc=='+')||(opc=='-')) && ( (q==off) || ( (q==p) && lastopc != '(') ) ) ) {
[2510]568 CE_BinExp* nbx;
[2515]569 if (opc == '+') nbx = new CE_AddExp;
570 else if (opc == '-') nbx = new CE_SubExp;
571 else if (opc == '*') nbx = new CE_MulExp;
572 else nbx = new CE_DivExp;
[2510]573 if ((p == q) && (rx == NULL)) {
[2520]574 checkok = false; p = q; osn = 0; fgcont = false;
[2510]575 delete nbx;
576 errmsg = "CExpressionEvaluator::ParseString() Syntax Error - rx==NULL (C)";
577 }
578 else {
579 if (p == q) cx = rx;
[4063]580 else cx = VarNameOrNumber(sex.substr(p-osn,q-p+osn));
[2510]581 rx = Arrange_CE_BinExpStack(sbx, cx, nbx);
[2520]582 p = q+1; osn = 0; lastopc = opc;
[2510]583 }
584 }
[2520]585 else {
586 // Traitement des signes +/- qui pourrait faire partie d'une constante numerique
587 p = q+1; osn++;
588 continue;
589 }
[2510]590 break;
591 default:
592 throw CExprException("CExpressionEvaluator::ParseString() BUG-BUG-BUG");
593 break;
594 } // Fin de switch
595 }
596 else { // dernier element
597 if ( (p<len) && (rx != NULL)) {
598 checkok = false; p = len-1; fgcont = false;
599 errmsg = "CExpressionEvaluator::ParseString() Syntax Error - rx!=NULL at end (D)";
600 }
601 else {
[4063]602 if (p<len) cx = VarNameOrNumber(sex.substr(p-osn));
[2510]603 else cx = rx;
604 rx = Arrange_CE_BinExpStack(sbx, cx);
605 stop = p = len; fgcont = false;
606 finok = true;
607 }
608 }
609 }
610 // cout << " DBG-ParseString-out stop= " << stop << " sex[stop]= " << sex[stop] << endl;
611 if (finok && checkok) {
612 if( !sbx.empty() ) {
613 checkok = false;
614 errmsg = "CExpressionEvaluator::ParseString() !sbx.empty() at the end (E)";
615 }
616 else {
617 checkok = rx->CheckE(errmsg);
618 }
619 }
620 if (!finok || !checkok || !rx) {
621 char buff[128];
622 if (errmsg.length() < 1) {
623 errmsg = "CExpressionEvaluator::ParseString() Error - " ;
624 if (!finok) errmsg += " !finok " ;
625 if (!checkok) errmsg += " !checkok " ;
626 if (!rx) errmsg += " !rx " ;
627 errmsg += " (F)";
[2593]628 }
629
630 if (apperrmsg) {
631 if (p<len)
632 sprintf(buff,"\n CExprError... %s <> %s ", sex.substr(0,p).c_str(),
633 sex.substr(p).c_str());
634 else sprintf(buff,"\n CExprError... %s <<", sex.c_str());
635 errmsg += buff;
[2510]636 }
637 if (rx) delete rx;
638 rx = NULL;
639 while (!sbx.empty()) {
640 delete sbx.top();
641 sbx.pop();
642 }
643 }
644 if (fx) delete fx;
645 return rx;
646}
647
648} // End of namespace SOPHYA
649
Note: See TracBrowser for help on using the repository browser.