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( '"' );
00043 forbiddenCharactersInVariables.insert( '\'' );
00044 forbiddenCharactersInVariables.insert( '<' );
00045 forbiddenCharactersInVariables.insert( ',' );
00046 forbiddenCharactersInVariables.insert( '>' );
00047 forbiddenCharactersInVariables.insert( '.' );
00048 forbiddenCharactersInVariables.insert( '?' );
00049 forbiddenCharactersInVariables.insert( '/' );
00050
00051
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
00111 os << "#include \"AIDA_Tuple_native/IEvaluatorExpressionBase.h\"" << std::endl;
00112
00113
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
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
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
00195 os << "#include \"AIDA_Tuple_native/IFilterExpressionBase.h\"" << std::endl;
00196
00197
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
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
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 ) {
00293 char c = expression[pos-1];
00294 if ( forbiddenCharactersInVariables.find( c ) == forbiddenCharactersInVariables.end() ) {
00295 isCharBeforeGood = false;
00296 }
00297 else if ( c == '\"' ) isCharBeforeGood = false;
00298 }
00299 bool isCharAfterGood = true;
00300 std::string::size_type posAfter = pos + variable.size();
00301 if ( isCharBeforeGood && posAfter < expression.size() ) {
00302 char c = expression[posAfter];
00303 if ( forbiddenCharactersInVariables.find( c ) == forbiddenCharactersInVariables.end() ) {
00304 isCharAfterGood = false;
00305 }
00306 else if ( c == '\"' ) isCharAfterGood = false;
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 }