From 9b94dff860a23b713a8c34c59bd8e7ea7ebfb0a2 Mon Sep 17 00:00:00 2001 From: nemu Date: Thu, 14 Jan 2010 13:11:07 +0000 Subject: [PATCH] some minor improvements towards fixing the boost::spirit problem for newer distributions. Needs a thorough checking on a newer linux distribution, i.e. at home --- src/classes/PFunction.cpp | 6 ++ src/tests/spirit/PFunction.cpp | 78 ++++++++++++++++-- src/tests/spirit/PFunction.h | 3 + src/tests/spirit/PFunctionGrammar.h | 115 ++++++++++++++++----------- src/tests/spirit/fcnInput.txt | 7 +- src/tests/spirit/spirit_fcn_test.cpp | 2 + src/tests/spirit/spirit_fcn_test.pro | 2 +- 7 files changed, 156 insertions(+), 57 deletions(-) diff --git a/src/classes/PFunction.cpp b/src/classes/PFunction.cpp index 296cb021..b1f75b8f 100644 --- a/src/classes/PFunction.cpp +++ b/src/classes/PFunction.cpp @@ -34,6 +34,8 @@ #include using namespace std; +#include // for stripping leading whitespace in std::string + #include "PFunction.h" //-------------------------------------------------------------------------- @@ -131,6 +133,7 @@ Bool_t PFunction::SetFuncNo() // get string from tree string str(i->value.begin(), i->value.end()); + boost::algorithm::trim(str); // extract function number from string status = sscanf(str.c_str(), "FUN%d", &funNo); @@ -178,6 +181,7 @@ void PFunction::FillFuncEvalTree(iter_t const& i, PFuncTreeNode &node) if (i->value.id() == PFunctionGrammar::realID) { // handle number str = string(i->value.begin(), i->value.end()); // get string + boost::algorithm::trim(str); status = sscanf(str.c_str(), "%lf", &dvalue); // convert string to Double_t node.fID = PFunctionGrammar::realID; // keep the ID node.fDvalue = dvalue; // keep the value @@ -190,6 +194,7 @@ void PFunction::FillFuncEvalTree(iter_t const& i, PFuncTreeNode &node) node.fDvalue = 0.0135538817; // keep the value } else if (i->value.id() == PFunctionGrammar::parameterID) { // handle parameter number str = string(i->value.begin(), i->value.end()); // get string + boost::algorithm::trim(str); if (strstr(str.c_str(), "-")) { node.fSign = true; status = sscanf(str.c_str(), "-PAR%d", &ivalue); // convert string to parameter number @@ -201,6 +206,7 @@ void PFunction::FillFuncEvalTree(iter_t const& i, PFuncTreeNode &node) // cout << endl << ">> parameterID: value = " << ivalue; } else if (i->value.id() == PFunctionGrammar::mapID) { // handle map number str = string(i->value.begin(), i->value.end()); // get string + boost::algorithm::trim(str); status = sscanf(str.c_str(), "MAP%d", &ivalue); // convert string to map number node.fID = PFunctionGrammar::mapID; // keep the ID node.fIvalue = ivalue; // keep the value diff --git a/src/tests/spirit/PFunction.cpp b/src/tests/spirit/PFunction.cpp index b57bab1c..77f505bd 100644 --- a/src/tests/spirit/PFunction.cpp +++ b/src/tests/spirit/PFunction.cpp @@ -34,6 +34,8 @@ #include using namespace std; +#include // for stripping leading whitespace in std::string + #include "PFunction.h" //-------------------------------------------------------------------------- @@ -111,6 +113,24 @@ PFunction::~PFunction() CleanupFuncEvalTree(); } +//-------------------------------------------------------------------------- +// InitNode (protected) +//-------------------------------------------------------------------------- +/** + *

+ * + * \param node + */ +void PFunction::InitNode(PFuncTreeNode &node) +{ + node.fID = 0; + node.fOperatorTag = 0; + node.fFunctionTag = 0; + node.fIvalue = 0; + node.fSign = false; + node.fDvalue = 0.0; +} + //------------------------------------------------------------- // CheckParameterRange (protected) //------------------------------------------------------------- @@ -143,9 +163,18 @@ bool PFunction::CheckParameterAndMapInTree(iter_t const& i) } else if (i->value.id() == PFunctionGrammar::parameterID) { assert(i->children.size() == 0); string str(i->value.begin(), i->value.end()); - cout << endl << "parameterID: value = " << str << endl; - sscanf(str.c_str(), "PAR%d", &value); -//cout << endl << ">> value = " << value << ", fParam.size() = " << fParam.size(); + boost::algorithm::trim(str); + cout << endl << "parameterID: value = '" << str << "'" << endl; + + bool minus_sign_present = false; + if (str[0] == '-') + minus_sign_present = true; +cout << endl << ">> minus_sign_present = " << minus_sign_present; + if (minus_sign_present) + sscanf(str.c_str(), "-PAR%d", &value); + else + sscanf(str.c_str(), "PAR%d", &value); +cout << endl << ">> value = " << value << ", fParam.size() = " << fParam.size() << endl << "----"; if (value > (int)fParam.size()) { // parameter number found > number of parameters cout << endl << "**ERROR**: found parameter " << str << " with only " << fParam.size() << " parameters present?!?"; fValid = false; @@ -226,6 +255,7 @@ bool PFunction::SetFuncNo(iter_t const& i) */ bool PFunction::GenerateFuncEvalTree() { + InitNode(fFunc); FillFuncEvalTree(fInfo.trees.begin(), fFunc); return true; @@ -246,18 +276,31 @@ void PFunction::FillFuncEvalTree(iter_t const& i, PFuncTreeNode &node) string str; PFuncTreeNode child; + InitNode(child); + if (i->value.id() == PFunctionGrammar::realID) { // handle number str = string(i->value.begin(), i->value.end()); // get string status = sscanf(str.c_str(), "%lf", &dvalue); // convert string to double node.fID = PFunctionGrammar::realID; // keep the ID node.fDvalue = dvalue; // keep the value // cout << endl << ">> realID: value = " << dvalue; + } else if (i->value.id() == PFunctionGrammar::constPiID) { // handle constant pi + node.fID = PFunctionGrammar::constPiID; // keep the ID + node.fDvalue = 3.14159265358979323846; // keep the value + } else if (i->value.id() == PFunctionGrammar::constGammaMuID) { // handle constant gamma_mu + node.fID = PFunctionGrammar::constGammaMuID; // keep the ID + node.fDvalue = 0.0135538817; // keep the value } else if (i->value.id() == PFunctionGrammar::parameterID) { // handle parameter number str = string(i->value.begin(), i->value.end()); // get string - status = sscanf(str.c_str(), "PAR%d", &ivalue); // convert string to parameter number - node.fID = PFunctionGrammar::parameterID; // keep the ID + if (strstr(str.c_str(), "-")) { + node.fSign = true; + status = sscanf(str.c_str(), " -PAR%d", &ivalue); // convert string to parameter number + } else { + status = sscanf(str.c_str(), " PAR%d", &ivalue); // convert string to parameter number + } + node.fID = PFunctionGrammar::parameterID; // keep the ID node.fIvalue = ivalue; // keep the value -// cout << endl << ">> parameterID: value = " << ivalue; +cout << endl << ">> parameterID: value = " << ivalue; } else if (i->value.id() == PFunctionGrammar::mapID) { // handle map number str = string(i->value.begin(), i->value.end()); // get string status = sscanf(str.c_str(), "MAP%d", &ivalue); // convert string to map number @@ -387,8 +430,17 @@ double PFunction::EvalNode(PFuncTreeNode &node) { if (node.fID == PFunctionGrammar::realID) { return node.fDvalue; + } else if (node.fID == PFunctionGrammar::constPiID) { + return node.fDvalue; + } else if (node.fID == PFunctionGrammar::constGammaMuID) { + return node.fDvalue; } else if (node.fID == PFunctionGrammar::parameterID) { - return fParam[node.fIvalue-1]; + double dval; + if (node.fSign) + dval = -fParam[node.fIvalue-1]; + else + dval = fParam[node.fIvalue-1]; + return dval; } else if (node.fID == PFunctionGrammar::mapID) { return fParam[fMap[node.fIvalue-1]-1]; } else if (node.fID == PFunctionGrammar::functionID) { @@ -513,6 +565,18 @@ long PFunction::EvalTreeExpression(iter_t const& i) fFuncString += string(i->value.begin(), i->value.end()); if (*i->value.begin() == '-') fFuncString += ")"; + } else if (i->value.id() == PFunctionGrammar::constPiID) { + assert(i->children.size() == 0); + cout << endl << "constPiID: children = " << i->children.size(); + cout << endl << "constPiID: " << string(i->value.begin(), i->value.end()); + cout << endl << "-----"; + fFuncString += string(i->value.begin(), i->value.end()); + } else if (i->value.id() == PFunctionGrammar::constGammaMuID) { + assert(i->children.size() == 0); + cout << endl << "constGammaMuID: children = " << i->children.size(); + cout << endl << "constGammaMuID: " << string(i->value.begin(), i->value.end()); + cout << endl << "-----"; + fFuncString += string(i->value.begin(), i->value.end()); } else if (i->value.id() == PFunctionGrammar::funLabelID) { assert(i->children.size() == 0); //SetFuncNo(i); diff --git a/src/tests/spirit/PFunction.h b/src/tests/spirit/PFunction.h index 491aa484..de5a27b4 100644 --- a/src/tests/spirit/PFunction.h +++ b/src/tests/spirit/PFunction.h @@ -68,6 +68,7 @@ typedef struct func_tree_node { int fOperatorTag; ///< tag for '+', '-', '*', '/' int fFunctionTag; ///< tag got "cos", "sin", ... int fIvalue; ///< for parameter numbers and maps + bool fSign; ///< for sign. true = '-', false = '+' double fDvalue; ///< for numbers vector children; ///< holding sub-tree } PFuncTreeNode; @@ -83,6 +84,8 @@ class PFunction { virtual double Eval(); protected: + virtual void InitNode(PFuncTreeNode &node); + virtual bool CheckParameterAndMapRange(); virtual bool CheckParameterAndMapInTree(iter_t const& i); virtual bool SetFuncNo(iter_t const& i); diff --git a/src/tests/spirit/PFunctionGrammar.h b/src/tests/spirit/PFunctionGrammar.h index a442970f..5bdfc940 100644 --- a/src/tests/spirit/PFunctionGrammar.h +++ b/src/tests/spirit/PFunctionGrammar.h @@ -37,9 +37,17 @@ using namespace std; //#define BOOST_SPIRIT_DEBUG -#include -#include -using namespace boost::spirit; +#include + +#if BOOST_VERSION >= 103800 +# include +# include + using namespace BOOST_SPIRIT_CLASSIC_NS; +#else +# include +# include + using namespace boost::spirit; +#endif typedef char const* iterator_t; typedef tree_match parse_tree_match_t; @@ -51,15 +59,17 @@ typedef parse_tree_match_t::tree_iterator iter_t; */ struct PFunctionGrammar : public grammar { - static const int realID = 1; - static const int funLabelID = 2; - static const int parameterID = 3; - static const int mapID = 4; - static const int functionID = 5; - static const int factorID = 6; - static const int termID = 7; - static const int expressionID = 8; - static const int assignmentID = 9; + static const int realID = 1; + static const int constPiID = 2; + static const int constGammaMuID = 3; + static const int funLabelID = 4; + static const int parameterID = 5; + static const int mapID = 6; + static const int functionID = 7; + static const int factorID = 8; + static const int termID = 9; + static const int expressionID = 10; + static const int assignmentID = 11; template struct definition @@ -67,53 +77,62 @@ struct PFunctionGrammar : public grammar definition(PFunctionGrammar const& /*self*/) { // Start grammar definition - real = leaf_node_d[ real_p ]; + real = leaf_node_d[ real_p ]; - fun_label = leaf_node_d[ ( lexeme_d[ "FUN" >> +digit_p ] ) ]; + const_pi = leaf_node_d[ str_p("PI") ]; - parameter = leaf_node_d[ ( lexeme_d[ "PAR" >> +digit_p ] ) ]; + const_gamma_mu = leaf_node_d[ str_p("GAMMA_MU") ]; - map = leaf_node_d[ ( lexeme_d[ "MAP" >> +digit_p ] ) ]; + fun_label = leaf_node_d[ ( lexeme_d[ "FUN" >> +digit_p ] ) ]; - function = lexeme_d[ root_node_d[ str_p("COS") ] >> ch_p('(') ] >> expression >> ch_p(')') - | lexeme_d[ root_node_d[ str_p("SIN") ] >> ch_p('(') ] >> expression >> ch_p(')') - | lexeme_d[ root_node_d[ str_p("TAN") ] >> ch_p('(') ] >> expression >> ch_p(')') - | lexeme_d[ root_node_d[ str_p("COSH") ] >> ch_p('(') ] >> expression >> ch_p(')') - | lexeme_d[ root_node_d[ str_p("SINH") ] >> ch_p('(') ] >> expression >> ch_p(')') - | lexeme_d[ root_node_d[ str_p("TANH") ] >> ch_p('(') ] >> expression >> ch_p(')') - | lexeme_d[ root_node_d[ str_p("ACOS") ] >> ch_p('(') ] >> expression >> ch_p(')') - | lexeme_d[ root_node_d[ str_p("ASIN") ] >> ch_p('(') ] >> expression >> ch_p(')') - | lexeme_d[ root_node_d[ str_p("ATAN") ] >> ch_p('(') ] >> expression >> ch_p(')') - | lexeme_d[ root_node_d[ str_p("ACOSH") ] >> ch_p('(') ] >> expression >> ch_p(')') - | lexeme_d[ root_node_d[ str_p("ASINH") ] >> ch_p('(') ] >> expression >> ch_p(')') - | lexeme_d[ root_node_d[ str_p("ATANH") ] >> ch_p('(') ] >> expression >> ch_p(')') - | lexeme_d[ root_node_d[ str_p("LOG") ] >> ch_p('(') ] >> expression >> ch_p(')') - | lexeme_d[ root_node_d[ str_p("LN") ] >> ch_p('(') ] >> expression >> ch_p(')') - | lexeme_d[ root_node_d[ str_p("EXP") ] >> ch_p('(') ] >> expression >> ch_p(')') - ; + parameter = leaf_node_d[ ( lexeme_d[ "PAR" >> +digit_p ] ) | + ( lexeme_d[ "-PAR" >> +digit_p ] ) ]; - factor = real - | parameter - | map - | function - | inner_node_d[ch_p('(') >> expression >> ch_p(')')] - ; + map = leaf_node_d[ ( lexeme_d[ "MAP" >> +digit_p ] ) ]; - term = factor >> - *( (root_node_d[ch_p('*')] >> factor) - | (root_node_d[ch_p('/')] >> factor) - ); + function = lexeme_d[ root_node_d[ str_p("COS") ] >> ch_p('(') ] >> expression >> ch_p(')') + | lexeme_d[ root_node_d[ str_p("SIN") ] >> ch_p('(') ] >> expression >> ch_p(')') + | lexeme_d[ root_node_d[ str_p("TAN") ] >> ch_p('(') ] >> expression >> ch_p(')') + | lexeme_d[ root_node_d[ str_p("COSH") ] >> ch_p('(') ] >> expression >> ch_p(')') + | lexeme_d[ root_node_d[ str_p("SINH") ] >> ch_p('(') ] >> expression >> ch_p(')') + | lexeme_d[ root_node_d[ str_p("TANH") ] >> ch_p('(') ] >> expression >> ch_p(')') + | lexeme_d[ root_node_d[ str_p("ACOS") ] >> ch_p('(') ] >> expression >> ch_p(')') + | lexeme_d[ root_node_d[ str_p("ASIN") ] >> ch_p('(') ] >> expression >> ch_p(')') + | lexeme_d[ root_node_d[ str_p("ATAN") ] >> ch_p('(') ] >> expression >> ch_p(')') + | lexeme_d[ root_node_d[ str_p("ACOSH") ] >> ch_p('(') ] >> expression >> ch_p(')') + | lexeme_d[ root_node_d[ str_p("ASINH") ] >> ch_p('(') ] >> expression >> ch_p(')') + | lexeme_d[ root_node_d[ str_p("ATANH") ] >> ch_p('(') ] >> expression >> ch_p(')') + | lexeme_d[ root_node_d[ str_p("LOG") ] >> ch_p('(') ] >> expression >> ch_p(')') + | lexeme_d[ root_node_d[ str_p("LN") ] >> ch_p('(') ] >> expression >> ch_p(')') + | lexeme_d[ root_node_d[ str_p("EXP") ] >> ch_p('(') ] >> expression >> ch_p(')') + ; - expression = term >> - *( (root_node_d[ch_p('+')] >> term) - | (root_node_d[ch_p('-')] >> term) - ); + factor = real + | const_pi + | const_gamma_mu + | parameter + | map + | function + | inner_node_d[ch_p('(') >> expression >> ch_p(')')] + ; - assignment = fun_label >> ch_p('=') >> expression; + term = factor >> + *( (root_node_d[ch_p('*')] >> factor) + | (root_node_d[ch_p('/')] >> factor) + ); + + expression = term >> + *( (root_node_d[ch_p('+')] >> term) + | (root_node_d[ch_p('-')] >> term) + ); + + assignment = (fun_label >> ch_p('=') >> expression); // End grammar definition // turn on the debugging info. BOOST_SPIRIT_DEBUG_RULE(real); + BOOST_SPIRIT_DEBUG_RULE(const_pi); + BOOST_SPIRIT_DEBUG_RULE(const_gamma_mu); BOOST_SPIRIT_DEBUG_RULE(fun_label); BOOST_SPIRIT_DEBUG_RULE(parameter); BOOST_SPIRIT_DEBUG_RULE(map); @@ -132,6 +151,8 @@ struct PFunctionGrammar : public grammar rule, parser_tag > map; rule, parser_tag > parameter; rule, parser_tag > fun_label; + rule, parser_tag > const_gamma_mu; + rule, parser_tag > const_pi; rule, parser_tag > real; rule, parser_tag > const& diff --git a/src/tests/spirit/fcnInput.txt b/src/tests/spirit/fcnInput.txt index 36c485a7..58d79838 100644 --- a/src/tests/spirit/fcnInput.txt +++ b/src/tests/spirit/fcnInput.txt @@ -18,9 +18,12 @@ PAR 1.0 2.1 3.5 -0.87 0.87 MAP 2 1 4 5 FUNCTIONS #fun0 = sin(par3/(par1+map2)) -fun1 = (sin(par1)*cos(par1)+((map1))) +#fun0 = 1.2+pi +#fun1 = gamma_mu +#fun2 = -par1*(sin(par2)*cos(par3)+((map1))) +#fun1 = cos(par1) #fun0 = par1 + map3 * cos(cos(par2 - map1)) -#fun8 = log(sin(par1)) + exp(-1.0*map2) +fun8 = -par1*log(sin(par1)) + exp(-1.0*map2) #fun1 = par1 + map1 * (0.01355+par1*(2.1 - (-2.3 / 3.4))) #fun2 = par1 * par2 - map3 #fun3 = -3.2 + (par2-par1)/(map2+map3) diff --git a/src/tests/spirit/spirit_fcn_test.cpp b/src/tests/spirit/spirit_fcn_test.cpp index 95de4210..2ef7c520 100644 --- a/src/tests/spirit/spirit_fcn_test.cpp +++ b/src/tests/spirit/spirit_fcn_test.cpp @@ -1,6 +1,8 @@ #include using namespace std; +#include + #include "PFunctionHandler.h" //----------------------------------------------------- diff --git a/src/tests/spirit/spirit_fcn_test.pro b/src/tests/spirit/spirit_fcn_test.pro index 0103ad86..36e1b0e4 100644 --- a/src/tests/spirit/spirit_fcn_test.pro +++ b/src/tests/spirit/spirit_fcn_test.pro @@ -19,6 +19,6 @@ HEADERS = PFunctionGrammar.h \ SOURCES = spirit_fcn_test.cpp \ PFunction.cpp \ PFunctionHandler.cpp - + TARGET=spirit_fcn_test