Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

ExpressionParser.cpp

Go to the documentation of this file.
00001 #include "ExpressionParser.h"
00002 
00003 #ifdef OLDSTREAMS
00004 # include <iostream>
00005 # include <strstream>
00006 # define istringstream istrstream
00007 #else
00008 # include <ostream>
00009 # include <sstream>
00010 #endif
00011 
00012 static bool areTablesInitialized = false;
00013 
00014 static std::set<char> forbiddenCharactersInVariables = std::set<char>();
00015 
00016 static void
00017 initializeTables() {
00018   forbiddenCharactersInVariables.insert( ' ' );
00019   forbiddenCharactersInVariables.insert( '`' );
00020   forbiddenCharactersInVariables.insert( '~' );
00021   forbiddenCharactersInVariables.insert( '!' );
00022   forbiddenCharactersInVariables.insert( '@' );
00023   forbiddenCharactersInVariables.insert( '#' );
00024   forbiddenCharactersInVariables.insert( '$' );
00025   forbiddenCharactersInVariables.insert( '%' );
00026   forbiddenCharactersInVariables.insert( '^' );
00027   forbiddenCharactersInVariables.insert( '&' );
00028   forbiddenCharactersInVariables.insert( '*' );
00029   forbiddenCharactersInVariables.insert( '(' );
00030   forbiddenCharactersInVariables.insert( ')' );
00031   forbiddenCharactersInVariables.insert( '-' );
00032   forbiddenCharactersInVariables.insert( '=' );
00033   forbiddenCharactersInVariables.insert( '+' );
00034   forbiddenCharactersInVariables.insert( '|' );
00035   forbiddenCharactersInVariables.insert( '\\' );
00036   forbiddenCharactersInVariables.insert( '{' );
00037   forbiddenCharactersInVariables.insert( '}' );
00038   forbiddenCharactersInVariables.insert( '[' );
00039   forbiddenCharactersInVariables.insert( ']' );
00040   forbiddenCharactersInVariables.insert( ';' );
00041   forbiddenCharactersInVariables.insert( ':' );
00042   forbiddenCharactersInVariables.insert( '"' ); // It look as if this is ignored
00043   forbiddenCharactersInVariables.insert( '\'' );
00044   forbiddenCharactersInVariables.insert( '<' );
00045   forbiddenCharactersInVariables.insert( ',' );
00046   forbiddenCharactersInVariables.insert( '>' );
00047   forbiddenCharactersInVariables.insert( '.' );
00048   forbiddenCharactersInVariables.insert( '?' );
00049   forbiddenCharactersInVariables.insert( '/' );
00050 
00051   // other white spaces or funny characters
00052   forbiddenCharactersInVariables.insert( '\n' );
00053   forbiddenCharactersInVariables.insert( '\t' );
00054   forbiddenCharactersInVariables.insert( '\r' );
00055 
00056   areTablesInitialized = true;
00057 }
00058 
00059 
00060 Anaphe::AIDA_Tuple_native::ExpressionParser::ExpressionParser():
00061   m_headerFiles(),
00062   m_namespaces()
00063 {
00064   if ( ! areTablesInitialized ) initializeTables();
00065 }
00066 
00067 Anaphe::AIDA_Tuple_native::ExpressionParser::~ExpressionParser()
00068 {}
00069 
00070 
00071 bool
00072 Anaphe::AIDA_Tuple_native::ExpressionParser::useHeaderFiles( const std::set< std::string >& headerFiles )
00073 {
00074   m_headerFiles = headerFiles;
00075   return true;
00076 }
00077 
00078 
00079 const std::set<std::string>&
00080 Anaphe::AIDA_Tuple_native::ExpressionParser::headerFilesUsed() const
00081 {
00082   return m_headerFiles;
00083 }
00084 
00085 
00086 bool
00087 Anaphe::AIDA_Tuple_native::ExpressionParser::useNamespaces( const std::set< std::string >& namespaces )
00088 {
00089   m_namespaces = namespaces;
00090   return true;
00091 }
00092 
00093 
00094 const std::set<std::string>&
00095 Anaphe::AIDA_Tuple_native::ExpressionParser::namespacesUsed() const
00096 {
00097   return m_namespaces;
00098 }
00099 
00100 
00101 std::set<std::string>
00102 Anaphe::AIDA_Tuple_native::ExpressionParser::mathematicalEvaluation( const std::string& expression,
00103                                                                      const std::map< std::string, std::string >& variablesToTypes,
00104                                                                      const std::string& functionName,
00105                                                                      std::ostream& os ) const
00106 {
00107   os << "/* START OF AUTOMATICALLY GENERATED FILE */" << std::endl;
00108   std::set<std::string> variablesUsed = findUsedVariables( expression, variablesToTypes );
00109 
00110   // include the base class header file
00111   os << "#include \"AIDA_Tuple_native/IEvaluatorExpressionBase.h\"" << std::endl;
00112 
00113   // include the other header files
00114   for ( std::set<std::string>::const_iterator iHeaderFile = m_headerFiles.begin();
00115         iHeaderFile != m_headerFiles.end(); ++iHeaderFile ) {
00116     os << "#include "<< *iHeaderFile << std::endl;
00117   }
00118   os << std::endl;
00119   for ( std::set<std::string>::const_iterator iNamespace = m_namespaces.begin();
00120         iNamespace != m_namespaces.end(); ++iNamespace ) {
00121     os << "using namespace "<< *iNamespace << ";" << std::endl;
00122   }
00123 
00124   // declaring this class
00125   std::string theClassName = "EvaluatorExpression_" + functionName;
00126   os << std::endl
00127      << "class " << theClassName << " : virtual public Anaphe::AIDA_Tuple_native::IEvaluatorExpressionBase {" << std::endl
00128      << "public:" << std::endl
00129      << "  " << theClassName << "(){}" << std::endl
00130      << "  ~" << theClassName << "(){}" << std::endl
00131      << "  bool bind( const std::map<std::string, void*>& args ) {" << std::endl;
00132   for ( std::set<std::string>::const_iterator iArgument = variablesUsed.begin();
00133         iArgument != variablesUsed.end(); ++iArgument ) {
00134     const std::string& variableName = *iArgument;
00135     std::string variableType = variablesToTypes.find( variableName )->second;
00136     if ( variableType == "AIDA::ITuple" ) variableType = "AIDA::Dev::IDevTuple";
00137     os << "    m_" << variableName << " = reinterpret_cast< const "
00138        << variableType << " *>( args.find(\"" << variableName << "\")->second );" << std::endl;
00139   }
00140   os << "    return true;" << std::endl
00141      << "  };" << std::endl
00142      << "  double evaluate() const {" << std::endl;
00143   for ( std::set<std::string>::const_iterator iArgument = variablesUsed.begin();
00144         iArgument != variablesUsed.end(); ++iArgument ) {
00145     const std::string& variableName = *iArgument;
00146     std::string variableType = variablesToTypes.find( variableName )->second;
00147     if ( variableType == "AIDA::ITuple" ) variableType = "AIDA::Dev::IDevTuple";
00148     os << "    const " << variableType << "& " << variableName << " = * m_" << variableName << ";" << std::endl;
00149   }
00150   if ( existsVariableInExpression( "return", expression ) ) {
00151     os << "    " << correctIdentation( expression ) << std::endl;
00152   }
00153   else {
00154     std::istringstream is( expression.c_str() );
00155     std::string str = "";
00156     is >> str;
00157     if ( str == "" ) {
00158       os << "    return 1.0;" << std::endl;
00159     }
00160     else {
00161       os << "    return ( " << expression << " );" << std::endl;
00162     }
00163   }
00164   os << "  }" << std::endl
00165      << "private:" << std::endl;
00166   for ( std::set<std::string>::const_iterator iArgument = variablesUsed.begin();
00167         iArgument != variablesUsed.end(); ++iArgument ) {
00168     const std::string& variableName = *iArgument;
00169     std::string variableType = variablesToTypes.find( variableName )->second;
00170     if ( variableType == "AIDA::ITuple" ) variableType = "AIDA::Dev::IDevTuple";
00171     os << "  const " << variableType << "* m_" << variableName << ";" << std::endl;
00172   }
00173   os << "};" << std::endl
00174      << std::endl;
00175 
00176   // Declaration of the factory
00177   os << "static Anaphe::AIDA_Tuple_native::IEvaluatorExpressionFactory<" << theClassName << "> factory;" << std::endl
00178      << "Anaphe::AIDA_Tuple_native::IEvaluatorExpressionBaseFactory& " << functionName << " = factory;\n" << std::endl;
00179 
00180   os << "/* END OF AUTOMATICALLY GENERATED FILE */" << std::endl;
00181   return variablesUsed;
00182 }
00183 
00184 
00185 std::set<std::string>
00186 Anaphe::AIDA_Tuple_native::ExpressionParser::logicalEvaluation( const std::string& expression,
00187                                                                 const std::map< std::string, std::string >& variablesToTypes,
00188                                                                 const std::string& functionName,
00189                                                                 std::ostream& os ) const
00190 {
00191   os << "/* START OF AUTOMATICALLY GENERATED FILE */" << std::endl;
00192   std::set<std::string> variablesUsed = findUsedVariables( expression, variablesToTypes );
00193 
00194   // include the base class header file
00195   os << "#include \"AIDA_Tuple_native/IFilterExpressionBase.h\"" << std::endl;
00196 
00197   // include the other header files
00198   for ( std::set<std::string>::const_iterator iHeaderFile = m_headerFiles.begin();
00199         iHeaderFile != m_headerFiles.end(); ++iHeaderFile ) {
00200     os << "#include "<< *iHeaderFile << std::endl;
00201   }
00202   os << std::endl;
00203   for ( std::set<std::string>::const_iterator iNamespace = m_namespaces.begin();
00204         iNamespace != m_namespaces.end(); ++iNamespace ) {
00205     os << "using namespace "<< *iNamespace << ";" << std::endl;
00206   }
00207 
00208   // declaring this class
00209   std::string theClassName = "FilterExpression_" + functionName;
00210   os << std::endl
00211      << "class " << theClassName << " : virtual public Anaphe::AIDA_Tuple_native::IFilterExpressionBase {" << std::endl
00212      << "public:" << std::endl
00213      << "  " << theClassName << "(){}" << std::endl
00214      << "  ~" << theClassName << "(){}" << std::endl
00215      << "  bool bind( const std::map<std::string, void*>& args ) {" << std::endl;
00216   for ( std::set<std::string>::const_iterator iArgument = variablesUsed.begin();
00217         iArgument != variablesUsed.end(); ++iArgument ) {
00218     const std::string& variableName = *iArgument;
00219     std::string variableType = variablesToTypes.find( variableName )->second;
00220     if ( variableType == "AIDA::ITuple" ) variableType = "AIDA::Dev::IDevTuple";
00221     os << "    m_" << variableName << " = reinterpret_cast< const "
00222        << variableType << " *>( args.find(\"" << variableName << "\")->second );" << std::endl;
00223   }
00224   os << "    return true;" << std::endl
00225      << "  };" << std::endl
00226      << "  bool accept() const {" << std::endl;
00227   for ( std::set<std::string>::const_iterator iArgument = variablesUsed.begin();
00228         iArgument != variablesUsed.end(); ++iArgument ) {
00229     const std::string& variableName = *iArgument;
00230     std::string variableType = variablesToTypes.find( variableName )->second;
00231     if ( variableType == "AIDA::ITuple" ) variableType = "AIDA::Dev::IDevTuple";
00232     os << "    const " << variableType << "& " << variableName << " = * m_" << variableName << ";" << std::endl;
00233   }
00234   if ( existsVariableInExpression( "return", expression ) ) {
00235     os << "    " << correctIdentation( expression ) << std::endl;
00236   }
00237   else {
00238     std::istringstream is( expression.c_str() );
00239     std::string str = "";
00240     is >> str;
00241     if ( str == "" ) {
00242       os << "    return true;" << std::endl;
00243     }
00244     else {
00245       os << "    return ( " << expression << " );" << std::endl;
00246     }
00247   }
00248   os << "  }" << std::endl
00249      << "private:" << std::endl;
00250   for ( std::set<std::string>::const_iterator iArgument = variablesUsed.begin();
00251         iArgument != variablesUsed.end(); ++iArgument ) {
00252     const std::string& variableName = *iArgument;
00253     std::string variableType = variablesToTypes.find( variableName )->second;
00254     if ( variableType == "AIDA::ITuple" ) variableType = "AIDA::Dev::IDevTuple";
00255     os << "  const " << variableType << "* m_" << variableName << ";" << std::endl;
00256   }
00257   os << "};" << std::endl
00258      << std::endl;
00259 
00260   // Declaration of the factory
00261   os << "static Anaphe::AIDA_Tuple_native::IFilterExpressionFactory<" << theClassName << "> factory;" << std::endl
00262      << "Anaphe::AIDA_Tuple_native::IFilterExpressionBaseFactory& " << functionName << " = factory;\n" << std::endl;
00263 
00264   os << "/* END OF AUTOMATICALLY GENERATED FILE */" << std::endl;
00265   return variablesUsed;
00266 }
00267 
00268 
00269 std::set<std::string>
00270 Anaphe::AIDA_Tuple_native::ExpressionParser::findUsedVariables( const std::string& expression,
00271                                                                 const std::map< std::string, std::string >& variablesToTypes ) const
00272 {
00273   std::set<std::string> variablesUsed;
00274   for ( std::map< std::string, std::string >::const_iterator iVariable = variablesToTypes.begin();
00275         iVariable != variablesToTypes.end(); ++iVariable ) {
00276     const std::string& variableName = iVariable->first;
00277     if ( existsVariableInExpression( variableName, expression ) ) variablesUsed.insert( variableName );
00278   }
00279   return variablesUsed;
00280 }
00281 
00282 
00283 bool
00284 Anaphe::AIDA_Tuple_native::ExpressionParser::existsVariableInExpression( const std::string& variable,
00285                                                                          const std::string& expression ) const
00286 {
00287   bool foundVariable = false;
00288   for ( std::string::size_type pos = expression.find( variable, 0 );
00289         pos != std::string::npos;
00290         pos = expression.find( variable, pos + variable.size() ) ) {
00291     bool isCharBeforeGood = true;
00292     if ( pos > 0 ) { // check the previous character
00293       char c = expression[pos-1];
00294       if ( forbiddenCharactersInVariables.find( c ) == forbiddenCharactersInVariables.end() ) {
00295         isCharBeforeGood = false;
00296       }
00297       else if ( c == '\"' ) isCharBeforeGood = false; // For some funny reason we have to include this !!!
00298     }
00299     bool isCharAfterGood = true;
00300     std::string::size_type posAfter = pos + variable.size();
00301     if ( isCharBeforeGood && posAfter < expression.size() ) { // check the character after
00302       char c = expression[posAfter];
00303       if ( forbiddenCharactersInVariables.find( c ) == forbiddenCharactersInVariables.end() ) {
00304         isCharAfterGood = false;
00305       }
00306       else if ( c == '\"' ) isCharAfterGood = false; // For some funny reason we have to include this !!!
00307     }
00308     if ( isCharBeforeGood && isCharAfterGood ) {
00309       foundVariable = true;
00310       break;
00311     }
00312   }
00313   return foundVariable;
00314 }
00315 
00316 
00317 std::string
00318 Anaphe::AIDA_Tuple_native::ExpressionParser::correctIdentation( const std::string& expression ) const
00319 {
00320   std::string output = "";
00321   for ( unsigned int iChar = 0; iChar < expression.size(); ++iChar ) {
00322     char c = expression[iChar];
00323     output += c;
00324     if ( c == '\n' || c == '\r' ) output += "    ";
00325   }
00326   return output;
00327 }

Generated on Tue Feb 18 17:51:19 2003 for AIDA_Tuple_native by doxygen1.2.16