Changeset 4063 in Sophya for trunk/SophyaLib/SysTools


Ignore:
Timestamp:
Apr 27, 2012, 12:34:31 AM (13 years ago)
Author:
ansari
Message:

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

Location:
trunk/SophyaLib/SysTools
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/SophyaLib/SysTools/cexpre.cc

    r3617 r4063  
    4545class CE_NumberExp : public CExprBase {
    4646public:
    47   CE_NumberExp(double v) { _val = v; }
     47  CE_NumberExp(double v) { _val = v; _pval=&_val; }
     48  CE_NumberExp(double* pv) { _pval=pv; _val = *_pval; }
    4849  CE_NumberExp(string const & s);
    4950  virtual ~CE_NumberExp() {}
    50   virtual double Evaluate() const { return _val; } 
    51   virtual void  Print(ostream& os) const { os << _val; }
     51  virtual double Evaluate() const { return (*_pval); } 
     52  virtual void  Print(ostream& os) const { os << (*_pval); }
    5253protected:
    5354  double _val;
     55  double* _pval;
    5456};
    5557
    5658CE_NumberExp::CE_NumberExp(string const & s)
    5759{
     60  _pval=&_val;
    5861  size_t l = s.length();
    5962  if (l < 1) {
     
    6467  else if (s == "E") _val = M_E;
    6568  else {
    66     string errmsg = "CE_NumberExp::CE_NumberExp() Bad numerical constant: ";
     69    string errmsg = "CE_NumberExp::CE_NumberExp() Bad numerical constant or unknown variable: ";
    6770    errmsg += s;
    6871   
     
    349352
    350353/*!
    351   Parse the string \c sex and builds an expression.
    352   Can throw CExprException exception.
    353 */
    354 CExpressionEvaluator::CExpressionEvaluator(string const & sex)
     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.
     356*/
     357CExpressionEvaluator::CExpressionEvaluator(const char* exp, CE_VarListInterface* varlist)
    355358{
    356359  _exp = NULL;
     360  _varlist = varlist;
     361  size_t off=0,stop=0;
     362  string fname = "";
     363  string errmsg;
     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;
    357377  size_t off=0,stop=0;
    358378  string fname = "";
     
    402422}
    403423
     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}
    404431
    405432CExprBase* CExpressionEvaluator::ParseString(int extype, string fname, string const & sex,
     
    506533            errmsg = "CExpressionEvaluator::ParseString()/ Syntax Error - rx&&cx (B)";
    507534          }
    508           if (q > p) cx = new CE_NumberExp(sex.substr(p-osn,q-p+osn));
     535          if (q > p) cx = VarNameOrNumber(sex.substr(p-osn,q-p+osn));
    509536          else cx = rx;
    510537         
     
    551578            else {
    552579              if (p == q)  cx = rx;
    553               else cx = new CE_NumberExp(sex.substr(p-osn,q-p+osn));
     580              else cx = VarNameOrNumber(sex.substr(p-osn,q-p+osn));
    554581              rx = Arrange_CE_BinExpStack(sbx, cx, nbx);
    555582              p = q+1;  osn = 0; lastopc = opc;
     
    573600      }
    574601      else {
    575         if (p<len)  cx = new CE_NumberExp(sex.substr(p-osn));
     602        if (p<len)  cx = VarNameOrNumber(sex.substr(p-osn));
    576603        else cx = rx;
    577604        rx = Arrange_CE_BinExpStack(sbx, cx);
  • trunk/SophyaLib/SysTools/cexpre.h

    r3586 r4063  
    99#include <iostream>
    1010#include <string>
     11#include <vector>
     12#include <map>
    1113#include "pexceptions.h"
    1214
     
    4648};
    4749
     50
    4851/*!
    4952  \ingroup SysTools
     
    5356  {  ex.Print(s);  return(s);  }
    5457
     58/*!
     59  \ingroup SysTools
     60  \brief Interface class used by the CExpressionEvaluator class to represent a list of variables
     61  or named values accessible trough a pointer.
     62
     63  Inherited class should define the \b GetVarPointer() method, and can optionaly redefine
     64  the \b Update() method.
     65  \sa CExpressionEvaluator
     66*/
     67class CE_VarListInterface {
     68public:
     69  //! To be called to update values corresponding to the pointers. Default implementation does nothing.
     70  virtual void Update() { return; }
     71  //! Return a pointer to a double containing the value associated with \t name. 
     72  virtual double* GetVarPointer(std::string const& name) = 0;
     73};
     74
     75
    5576class CE_BinExp;
    5677class CE_FuncExp;
     
    5879class CExpressionEvaluator : public CExprBase {
    5980public:
    60   CExpressionEvaluator(string const & sex);
     81  CExpressionEvaluator(const char* sexp, CE_VarListInterface* pvlist=NULL);
     82  CExpressionEvaluator(string const & sex, CE_VarListInterface* pvlist=NULL);
     83
    6184  virtual ~CExpressionEvaluator();
    6285//! Evaluate the expression and returns the corresponding value.
     
    6891
    6992protected:
     93//! Parse variable names or constants and return CE_NumberExp object.
     94  CExprBase* VarNameOrNumber(string const & s);
    7095//! Does the parsing and builds an CExprBase object.
    7196  CExprBase* ParseString(int extype, string fname, string const & sex,
     
    7398
    7499  CExprBase * _exp;
     100  CE_VarListInterface* _varlist;
    75101};
    76102
  • trunk/SophyaLib/SysTools/commander.cc

    r4034 r4063  
    442442
    443443// ------------------------------------------------------------
     444//         Classe Cmd_CE_VarList
     445// ------------------------------------------------------------
     446/*!
     447  \internal
     448  \class SOPHYA::Cmd_CE_VarList
     449  \ingroup SysTools
     450  This class, reserved for internal use by class Commander, enables the CExpressionEvaluator class
     451  to access the interpreter variable values.
     452*/
     453
     454class Cmd_CE_VarList : public CE_VarListInterface {
     455public:
     456  Cmd_CE_VarList(Commander& cmd) : cmd_(cmd) { }
     457  virtual void Update();
     458  virtual double* GetVarPointer(std::string const& name);
     459private:
     460  Commander& cmd_;
     461  std::map<std::string, double> namevals_;
     462};
     463
     464/* --Methode-- */
     465void Cmd_CE_VarList::Update()
     466{
     467  bool exist=false;
     468  string sval;
     469  std::map<std::string, double>::iterator it;
     470  for(it=namevals_.begin(); it!=namevals_.end(); it++) {
     471    exist=cmd_.GetVar((*it).first, sval);
     472    if (!exist) throw NotFoundExc("Cmd_CE_VarList::Update() missing variable !");
     473    (*it).second=atof(sval.c_str());
     474  }
     475  return;
     476}
     477
     478/* --Methode-- */
     479double* Cmd_CE_VarList::GetVarPointer(std::string const& name)
     480{
     481  std::map<std::string, double>::iterator it=namevals_.find(name);
     482  if (it!=namevals_.end())  return &((*it).second);
     483  bool exist=false;
     484  string sval;
     485  exist=cmd_.GetVar(name, sval);
     486  if (!exist) return NULL;
     487  namevals_[name]=atof(sval.c_str());
     488  it=namevals_.find(name);
     489  if (it!=namevals_.end())  return &((*it).second);
     490  return NULL;
     491}
     492
     493
     494// ------------------------------------------------------------
    444495//         Classe Commander
    445496// ------------------------------------------------------------
     
    492543hist.open("history.pic");
    493544histon = true;
    494 trace = false;   timing = false;
     545trace = false;   timing = false;   varcexp = true;
    495546gltimer = NULL;
    496547felevel_ = 0;
     
    561612usage += "  > sleep nsec  # sleep nsec seconds \n";   
    562613usage += "  > readstdin varname      # reads a line from stdin into $varname \n";
    563 usage += "  > timingon  timingoff traceon  traceoff \n";
     614usage += "  > timingon  timingoff traceon  traceoff varcexpon varcexpoff \n";
    564615RegisterHelp(kw, usage, grp);
    565616
     
    10851136    try {
    10861137      double res = 0.;
    1087       if (tokens.size() > 2) {
    1088         string sex = tokens[1];
     1138      string sex=tokens[1];
     1139      if (tokens.size() > 2)
    10891140        for(unsigned int js=2; js<tokens.size(); js++)  sex += tokens[js];
    1090         CExpressionEvaluator cex(sex);
     1141      if (varcexp) {  //--- Evaluation d'expression avec decodage de noms de variables 
     1142        Cmd_CE_VarList cevl(*this);
     1143        CExpressionEvaluator cex(sex,&cevl);
    10911144        res = cex.Value();
    10921145      }
    1093       else {
    1094         CExpressionEvaluator cex(tokens[1]);
     1146      else {  //--- Evaluation d'expression SANS decodage des noms de variables 
     1147        CExpressionEvaluator cex(sex);
    10951148        res = cex.Value();
    10961149      }
     
    19572010  if (gltimer)  delete gltimer;  gltimer = NULL;  timing = false;
    19582011  }
     2012else if (kw == "varcexpon") 
     2013  { cout << "Commander::Interpret()  -> Activating variable name decoding in expression evaluation " << endl; varcexp = true; }
     2014else if (kw == "varcexpoff")
     2015  { cout << "Commander::Interpret()  -> Deactivating variable name decoding in expression evaluation " << endl; varcexp = false; }
    19592016else if (kw == "exec") {
    19602017  if (tokens.size() < 1) { cout << "Commander::Interpret() Usage: exec filename" << endl;  return(0); }
  • trunk/SophyaLib/SysTools/commander.h

    r4034 r4063  
    257257  bool timing;         // Display CPU Time
    258258  Timer* gltimer;      // pour Display CPU Time
    259 
     259  bool varcexp;      // true -> decodage nom de variables lors d'evaluation d'expression
    260260friend class CommanderBloc; 
    261261friend class CommanderScript; 
Note: See TracChangeset for help on using the changeset viewer.