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