Main Page | Class Hierarchy | Class List | Directories | File List | Class Members

expression.h

00001 /***************************************************************************
00002  *   Copyright (C) 2004-2006 by Radko Mihal                                *
00003  *   rmihal@pobox.sk                                                       *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.              *
00019  ***************************************************************************/
00020 #ifndef EXPRESSION_H
00021 #define EXPRESSION_H
00022 
00044 template< class Type >
00045 class expression
00046 {       
00047         enum priorities { plus_minus=0, multiply_divide = 1, fnc_value_parenthesis = 2 };
00048         
00049 typedef std::string std_string; 
00050         class subexpression
00051         {
00052                 class parentheses
00053                 {
00054                         grammar_to_parser::pattern_parser                                       m_left;
00055                         grammar_to_parser::choice< expression<Type> >           m_e;
00056                         grammar_to_parser::pattern_parser                                       m_right;
00057                 public:
00058                         parentheses() : 
00059                                 m_left(std_string(1,'(') ), m_right(std_string(1,')') ) {};
00060                         void push_parsers( grammar_to_parser::parsers& l )
00061                         {
00062                                 l.push_back( &m_left );
00063                                 l.push_back( &m_e );
00064                                 l.push_back( &m_right );
00065                         }
00066                         Type evaluate()
00067                         {
00068                                 return m_e->evaluate();
00069                         }
00070                 };
00071 
00072                 grammar_to_parser::non_terminal<parentheses>    m_para;
00073                 grammar_to_parser::choice< functions<Type> >    m_fnc;
00074                 grammar_to_parser::choice< values<Type> >               m_val;
00075         public:
00076                 void push_parsers( grammar_to_parser::parsers& l )
00077                 {
00078                         l.push_back( &m_para );
00079                         l.push_back( &m_fnc );
00080                         l.push_back( &m_val );
00081                 }
00082                 int get_priority() { return fnc_value_parenthesis; }
00083                 Type evaluate()
00084                 {
00085                         if( m_para.is_parsed() ) return m_para->evaluate();
00086                         if( m_fnc.is_parsed() ) return m_fnc->evaluate();
00087                         if( m_val.is_parsed() ) return m_val->evaluate();
00088                         return 0;
00089                 }
00090         };
00091         
00092         class add
00093         {
00094                 grammar_to_parser::choice< subexpression >              m_subexpr;
00095                 grammar_to_parser::pattern_parser                               m_plus;
00096                 grammar_to_parser::choice< expression<Type> >   m_expr;
00097         public:
00098                 add() : m_plus( std_string(1,'+') ) {}
00099                 
00100                 void push_parsers( grammar_to_parser::parsers& l )
00101                 {
00102                         l.push_back( &m_subexpr );
00103                         l.push_back( &m_plus );
00104                         l.push_back( &m_expr );
00105                 }
00106 
00107                 Type evaluate()
00108                 {
00109                         return m_subexpr->evaluate() + m_expr->evaluate();
00110                 }
00111                 
00112                 // this method is called for example in this case: 5-4+3, at first 
00113                 // must be evaluated 5-4 - which is the left_result, 
00114                 // then the 4 is added
00115                 Type evaluate( Type left_result )
00116                 {
00117                         return left_result + m_expr->evaluate();
00118                 }
00119                 
00120                 // this method is called for example in this case: 5-4+3, first must be 
00121                 // evaluated 5-4 ... the 4 value for 'left' 
00122                 // expression is obtained using get_left_value() call
00123                 Type get_left_value()
00124                 {
00125                         return m_subexpr->evaluate();
00126                 }
00127                 int get_priority() { return plus_minus; }
00128         };
00129 
00130         class substract
00131         {
00132                 grammar_to_parser::choice< subexpression >              m_subexpr;
00133                 grammar_to_parser::pattern_parser                               m_minus;
00134                 grammar_to_parser::choice< expression<Type> >   m_expr;
00135         public:
00136                 substract() : m_minus( std_string(1,'-') ) {};
00137                 void push_parsers( grammar_to_parser::parsers& l )
00138                 {
00139                         l.push_back( &m_subexpr );
00140                         l.push_back( &m_minus );
00141                         l.push_back( &m_expr );
00142                 }
00143 
00144                 Type evaluate()
00145                 {
00146                         if( m_expr->get_priority() <= get_priority() )
00147                         {
00148                                 // first the left value from expression must be 
00149                                 // substracted from 5, then evaluate of the 
00150                                 // expression with result
00151                                 return m_expr->evaluate( 
00152                                                         m_subexpr->evaluate() - m_expr->get_left_value() );
00153                         }
00154                         else
00155                         {
00156                                 return m_subexpr->evaluate() - m_expr->evaluate();
00157                         }
00158                 }
00159                 
00160                 Type evaluate( Type left_result )
00161                 {
00162                         // !!ERR!! - BEGIN (in 1.6)    5-4-3-2 returned wrong result (0)
00163                         if( m_expr->get_priority() <= get_priority() )
00164                         {
00165                                 // first the left value from expression must be 
00166                                 // substracted from 5, then evaluate of the 
00167                                 // expression with result
00168                                 return m_expr->evaluate( left_result - m_expr->get_left_value() );
00169                         }
00170                         else
00171                         {
00172                                 return left_result - m_expr->evaluate();
00173                         }
00174                         //return left_result - m_expr->evaluate();
00175                         // !!ERR!! - end
00176                 }
00177                 
00178                 Type get_left_value()
00179                 {
00180                         return m_subexpr->evaluate();
00181                 }
00182                 
00183                 int get_priority() { return plus_minus; }
00184         };
00185         
00186         class multiply
00187         {
00188                 grammar_to_parser::choice< subexpression >              m_subexpr;
00189                 grammar_to_parser::pattern_parser                               m_multiply;
00190                 grammar_to_parser::choice< expression<Type> >   m_expr;
00191         public:
00192                 multiply() : m_multiply(std_string(1,'*') ) {};
00193                 void push_parsers( grammar_to_parser::parsers& l )
00194                 {
00195                         l.push_back( &m_subexpr );
00196                         l.push_back( &m_multiply );
00197                         l.push_back( &m_expr );
00198                 }
00199 
00200                 Type evaluate()
00201                 {
00202                         if( m_expr->get_priority() <= get_priority() )
00203                         {
00204                                 return m_expr->evaluate( 
00205                                                         m_subexpr->evaluate() * m_expr->get_left_value() );
00206                         }
00207                         else
00208                         {
00209                                 return m_subexpr->evaluate() * m_expr->evaluate();
00210                         }
00211                 }
00212                 
00213                 Type evaluate( Type left_result )
00214                 {
00215                         return left_result * m_expr->evaluate();
00216                 }
00217                 
00218                 Type get_left_value()
00219                 {
00220                         return m_subexpr->evaluate();
00221                 }
00222                 
00223                 int get_priority() { return multiply_divide; }
00224         };
00225         
00226         class divide
00227         {
00228                 grammar_to_parser::choice< subexpression >              m_subexpr;
00229                 grammar_to_parser::pattern_parser                               m_div;
00230                 grammar_to_parser::choice< expression<Type> >   m_expr;
00231         public:
00232                 divide() : m_div( std_string(1,'/') ) {};
00233                 void push_parsers( grammar_to_parser::parsers& l )
00234                 {
00235                         l.push_back( &m_subexpr );
00236                         l.push_back( &m_div );
00237                         l.push_back( &m_expr );
00238                 }
00239 
00240                 Type evaluate()
00241                 {
00242                         if( m_expr->get_priority() <= get_priority() )
00243                         {
00244                                 return m_expr->evaluate( 
00245                                                         m_subexpr->evaluate() / m_expr->get_left_value() );
00246                         }
00247                         else
00248                         {
00249                                 return m_subexpr->evaluate() / m_expr->evaluate();
00250                         }
00251                 }
00252                 
00253                 Type evaluate( Type left_result )
00254                 {
00255                         // !!ERR!! - BEGIN (in 1.6)
00256                         if( m_expr->get_priority() <= get_priority() )
00257                         {
00258                                 return m_expr->evaluate( left_result / m_expr->get_left_value() );
00259                         }
00260                         else
00261                         {
00262                                 return left_result / m_expr->evaluate();
00263                         }                       
00264                         // return left_result / m_expr->evaluate();
00265                         // !!ERR!! - END
00266                 }
00267                 
00268                 Type get_left_value()
00269                 {
00270                         return m_subexpr->evaluate();
00271                 }
00272                 
00273                 int get_priority() { return multiply_divide; }
00274         };
00275 
00276 protected:
00277         grammar_to_parser::non_terminal<add>                    m_add;
00278         grammar_to_parser::non_terminal<substract>              m_substract;
00279         grammar_to_parser::non_terminal<multiply>               m_multiply;
00280         grammar_to_parser::non_terminal<divide>                 m_divide;
00281         grammar_to_parser::choice<subexpression>                m_subexpr;
00282 public:
00283         
00284         expression() {};
00285         ~expression() {};
00286                         
00287         void push_parsers( grammar_to_parser::parsers& l )
00288         {
00289                 l.push_back( &m_add );
00290                 l.push_back( &m_substract );
00291                 l.push_back( &m_multiply );
00292                 l.push_back( &m_divide );
00293                 l.push_back( &m_subexpr );
00294         }
00295 
00296         Type evaluate()
00297         {
00298                 if( m_subexpr.is_parsed() ) return m_subexpr->evaluate();
00299                 if( m_divide.is_parsed() ) return m_divide->evaluate();
00300                 if( m_multiply.is_parsed() ) return m_multiply->evaluate();
00301                 if( m_add.is_parsed() ) return m_add->evaluate();
00302                 if( m_substract.is_parsed() ) return m_substract->evaluate();
00303                 return 0;
00304         }
00305         
00306         Type evaluate( Type left_result )
00307         {
00308                 if( m_divide.is_parsed() ) return m_divide->evaluate(left_result);
00309                 if( m_multiply.is_parsed() ) return m_multiply->evaluate(left_result);
00310                 if( m_add.is_parsed() ) return m_add->evaluate(left_result);
00311                 if( m_substract.is_parsed() ) return m_substract->evaluate(left_result);
00312         }
00313         
00314         Type get_left_value()
00315         {
00316                 // this has only left value - thus call evaluate directly
00317                 if( m_subexpr.is_parsed() ) return m_subexpr->evaluate();
00318                 // following have alse left side = left value
00319                 if( m_divide.is_parsed() ) return m_divide->get_left_value();
00320                 if( m_multiply.is_parsed() ) return m_multiply->get_left_value();
00321                 if( m_add.is_parsed() ) return m_add->get_left_value();
00322                 if( m_substract.is_parsed() ) return m_substract->get_left_value();
00323         }
00324         
00325         int get_priority()
00326         {
00327                 if( m_subexpr.is_parsed() ) return m_subexpr->get_priority();
00328                 if( m_divide.is_parsed() ) return m_divide->get_priority();
00329                 if( m_multiply.is_parsed() ) return m_multiply->get_priority();
00330                 if( m_add.is_parsed() ) return m_add->get_priority();
00331                 if( m_substract.is_parsed() ) return m_substract->get_priority();
00332         }
00333 }; // expression
00334 
00335 #endif

Generated on Sun Jul 2 18:39:43 2006 for grammar2parser.kdevelop by  doxygen 1.4.1