Main Page | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Namespace Members | Data Fields | Globals

expr.h

Go to the documentation of this file.
00001 #if !defined( __EXPR_H__ )
00002 #define __EXPR_H__
00003 
00004 class Expr      : public Lexer  {
00005 
00006         static const char sr[10][10];
00007 
00008 
00009 public:
00010 
00011         Expr( const string &aBuffer );
00012 
00013         virtual const char      atSr( const int ati , const int atj )   {       return sr[ati][atj];    }
00014         virtual const int EofId( void ) const;
00015         virtual const int IdentifierId( void ) const;
00016         virtual const int NumberId( void ) const;
00017 };
00018 
00019 class ExprParser        {
00020 private:
00021 
00022         map<string,Random *>    variables;
00023 
00024         class Context   {
00025         public:
00026 
00028                 map<string,Random *>    &variables;
00029                 Random  *rdm;
00030                 double  val;
00031 
00032                 Context( map<string,Random *> &aVar )
00033                 : variables( aVar ) , val( 0.0 ) , rdm( 0 )
00034                 {}
00035                 
00036                 Context( Context &ctx )
00037                 : variables( ctx.variables ) , val( 0.0 ) , rdm( 0 )
00038                 {}
00039 
00040                 Context &operator=( Context &ctx )
00041                 {
00042                         rdm = ctx.rdm;
00043                         val = ctx.val;
00044                         return *this;
00045                 }
00046 
00047                 Context &operator+=( Context &ctx )
00048                 {
00049                         if( rdm )
00050                                 if( ctx.rdm )
00051                                         rdm = &(*rdm + *(ctx.rdm));
00052                                 else
00053                                         rdm = &(*rdm + ctx.val);
00054                         else if( ctx.rdm )
00055                                 rdm = &(val + *(ctx.rdm));
00056                         else
00057                                 val += ctx.val;
00058                         return *this;
00059                 }
00060                 Context &operator-=( Context &ctx )
00061                 {
00062                         if( rdm )
00063                                 if( ctx.rdm )
00064                                         rdm = &(*rdm - *(ctx.rdm));
00065                                 else
00066                                         rdm = &(*rdm - ctx.val);
00067                         else if( ctx.rdm )
00068                                 rdm = &(val - *(ctx.rdm));
00069                         else
00070                                 val -= ctx.val;
00071                         return *this;
00072                 }
00073                 Context &operator*=( Context &ctx )
00074                 {
00075                         if( rdm )
00076                                 if( ctx.rdm )
00077                                         rdm = &(*rdm * *(ctx.rdm));
00078                                 else
00079                                         rdm = &(*rdm * ctx.val);
00080                         else if( ctx.rdm )
00081                                 rdm = &(val * *(ctx.rdm));
00082                         else
00083                                 val *= ctx.val;
00084                         return *this;
00085                 }
00086                 Context &operator/=( Context &ctx )
00087                 {
00088                         if( rdm )
00089                                 if( ctx.rdm )
00090                                         rdm = &(*rdm / *(ctx.rdm));
00091                                 else
00092                                         rdm = &(*rdm / ctx.val);
00093                         else if( ctx.rdm )
00094                                 rdm = &(val / *(ctx.rdm));
00095                         else
00096                                 val /= ctx.val;
00097                         return *this;
00098                 }
00099                 Context &operator|=( Context &ctx )
00100                 {
00101                         if( rdm && ctx.rdm )
00102                                 rdm = &(*rdm | *(ctx.rdm));
00103                         else
00104                                 val = (int)val | (int)ctx.val;
00105                         return *this;
00106                 }
00107         };
00108 
00109         Interpret       *itp;
00110 
00111 public:
00112 
00113         ExprParser( void ) : itp( 0 )
00114         {
00115         }
00116 
00117         virtual ~ExprParser( void )
00118         {
00119                 if( itp )
00120                         delete itp;
00121                 itp = 0;
00122 
00123         }
00124 
00125         TreeNode *Eval( const string &aBuffer )
00126         {
00127                 Expr    lex( aBuffer );
00128                 itp = new Interpret( lex );
00129                 itp->Run();
00130                 if( !itp->empty() )
00131                         return itp->back();
00132                 return 0;
00133         }
00134 
00135         SumRandom *Apply( TreeNode *tn )
00136         {
00137                 if( tn )
00138                 {
00139                         Context ctx( variables );
00140                         WalkTree( tn , ctx );
00141                         return new SumRandom( *ctx.rdm );
00142                 }
00143                 return 0;
00144         }
00145 
00146         static vector<Uniform *>        toDelinExprParser;
00147 
00148 private:
00149 
00150         void WalkTree( TreeNode *tn , Context &ctx )
00151         {
00152                 if( tn )
00153                 {
00154                         Context lctx( ctx );
00155                         if( tn->child != 0 )
00156                                 WalkTree( tn->child , lctx );
00157 
00158                         Context rctx( ctx );
00159                         if( tn->next != 0 )
00160                                 WalkTree( tn->next , rctx );
00161 
00162                         if( tn->symbolId == 9 )         
00163                                 ctx.val = atof( tn->constant.c_str() );
00164                         else if( tn->symbolId == 5 )
00165                         {
00166                                 map<string,Random *>::iterator  pos = ctx.variables.find( tn->constant );
00167                                 if( pos == ctx.variables.end() )
00168                                 {
00169                                         ctx.variables.insert( make_pair( tn->constant , ctx.rdm = new Uniform ) );
00170                                         toDelinExprParser.push_back( dynamic_cast<Uniform *>( ctx.rdm ) );
00171                                 }
00172                                  else
00173                                          ctx.rdm = pos->second;
00174                         }
00175                         else
00176                         {
00177                                 ctx = lctx;     
00178 
00179                                 switch( tn->constant.c_str()[0] )
00180                                 {
00181                                         case '+' : ctx += rctx; break;
00182                                         case '-' : ctx -= rctx; break;
00183                                         case '*' : ctx *= rctx; break;
00184                                         case '/' : ctx /= rctx; break;
00185                                         case '|' : ctx |= rctx; break;
00186                                         default:
00187                                                 if( lctx.rdm != 0 )
00188                                                         ctx = lctx;
00189                                                 if( rctx.rdm != 0 )
00190                                                         if( ctx.rdm == 0 )
00191                                                                 ctx = rctx;
00192                                                         else
00193                                                                 printf( "ERROR\n" );
00194                                                 break;
00195                                 }
00196                         }
00197                 }
00198         }
00199 };
00200 
00201 #endif

Generated on Fri Dec 5 04:05:59 2003 for Borqueror by doxygen 1.3.3