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