From 18a45afea110fc503a01debd57696312242c5549 Mon Sep 17 00:00:00 2001 From: nemu Date: Mon, 18 Feb 2008 07:43:57 +0000 Subject: [PATCH] fixed a bug in the FUNCTIONS parsing. Now the AST is generated correctly also for (sin(par1)), etc. Also added gamma_mu in FUNCTIONS --- src/ToDo.txt | 2 + src/classes/PFunction.cpp | 26 +++++--- src/include/PFunctionGrammar.h | 100 +++++++++++++++------------- src/tests/spirit/PFunction.cpp | 69 ++++++++----------- src/tests/spirit/PFunctionGrammar.h | 32 ++++----- src/tests/spirit/fcnInput.txt | 2 +- 6 files changed, 116 insertions(+), 115 deletions(-) diff --git a/src/ToDo.txt b/src/ToDo.txt index 4248d279..decb339f 100644 --- a/src/ToDo.txt +++ b/src/ToDo.txt @@ -29,6 +29,8 @@ short term: * implement max.likelihood fits **DONE** 08-02-06 (for Single Histo only. For the others not clear how to do it.) +* fix problems in FUNCTIONS of the form (sin(par1)) **DONE** 08-02-18 + * implement table based theory functions (LF stuff) * if a parameter is not used at all, minuit is still varying it!! This is stupid. diff --git a/src/classes/PFunction.cpp b/src/classes/PFunction.cpp index 3d4a5ada..f31127a8 100644 --- a/src/classes/PFunction.cpp +++ b/src/classes/PFunction.cpp @@ -164,6 +164,9 @@ void PFunction::FillFuncEvalTree(iter_t const& i, PFuncTreeNode &node) } 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.01355; // 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 @@ -180,9 +183,7 @@ void PFunction::FillFuncEvalTree(iter_t const& i, PFuncTreeNode &node) // keep the id node.fID = PFunctionGrammar::functionID; // keep function tag - // i: 'funcName', '(', 'expression', ')' - iter_t it = i->children.begin(); - str = string(it->value.begin(), it->value.end()); // get string + str = string(i->value.begin(), i->value.end()); // get string // cout << endl << ">> functionID: value = " << str; if (!strcmp(str.c_str(), "COS")) node.fFunctionTag = FUN_COS; @@ -220,8 +221,8 @@ void PFunction::FillFuncEvalTree(iter_t const& i, PFuncTreeNode &node) } // add node node.children.push_back(child); - // i: 'funcName', '(', 'expression', ')' - FillFuncEvalTree(i->children.begin()+2, node.children[0]); + // i: '(', 'expression', ')' + FillFuncEvalTree(i->children.begin()+1, node.children[0]); } else if (i->value.id() == PFunctionGrammar::factorID) { // cout << endl << ">> factorID"; // keep the id @@ -306,6 +307,8 @@ bool PFunction::FindAndCheckMapAndParamRange(PFuncTreeNode &node, unsigned int m return true; } else if (node.fID == PFunctionGrammar::constPiID) { return true; + } else if (node.fID == PFunctionGrammar::constGammaMuID) { + return true; } else if (node.fID == PFunctionGrammar::parameterID) { if (node.fIvalue <= (int) paramSize) return true; @@ -365,6 +368,8 @@ double PFunction::EvalNode(PFuncTreeNode &node) 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]; } else if (node.fID == PFunctionGrammar::mapID) { @@ -496,6 +501,8 @@ void PFunction::EvalTreeForStringExpression(iter_t const& i) fFuncString += ")"; } else if (i->value.id() == PFunctionGrammar::constPiID) { fFuncString += "Pi"; + } else if (i->value.id() == PFunctionGrammar::constGammaMuID) { + fFuncString += "gamma_mu"; } else if (i->value.id() == PFunctionGrammar::funLabelID) { assert(i->children.size() == 0); //SetFuncNo(i); @@ -507,12 +514,11 @@ void PFunction::EvalTreeForStringExpression(iter_t const& i) assert(i->children.size() == 0); fFuncString += string(i->value.begin(), i->value.end()).c_str(); } else if (i->value.id() == PFunctionGrammar::functionID) { - assert(i->children.size() == 4); - iter_t it = i->children.begin(); - // funcName, '(', expression, ')' - fFuncString += string(it->value.begin(), it->value.end()).c_str(); + assert(i->children.size() == 3); + fFuncString += string(i->value.begin(), i->value.end()).c_str(); // keep function name fFuncString += "("; - EvalTreeForStringExpression(i->children.begin()+2); // the real stuff + // '(', expression, ')' + EvalTreeForStringExpression(i->children.begin()+1); // the real stuff fFuncString += ")"; } else if (i->value.id() == PFunctionGrammar::factorID) { EvalTreeForStringExpression(i->children.begin()); diff --git a/src/include/PFunctionGrammar.h b/src/include/PFunctionGrammar.h index 1c5f5be8..a8b0a442 100644 --- a/src/include/PFunctionGrammar.h +++ b/src/include/PFunctionGrammar.h @@ -51,16 +51,17 @@ typedef parse_tree_match_t::tree_iterator iter_t; */ struct PFunctionGrammar : public grammar { - static const int realID = 1; - static const int constPiID = 2; - static const int funLabelID = 3; - static const int parameterID = 4; - static const int mapID = 5; - static const int functionID = 6; - static const int factorID = 7; - static const int termID = 8; - static const int expressionID = 9; - static const int assignmentID = 10; + 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 @@ -68,57 +69,61 @@ struct PFunctionGrammar : public grammar definition(PFunctionGrammar const& /*self*/) { // Start grammar definition - real = leaf_node_d[ real_p ]; + real = leaf_node_d[ real_p ]; - const_pi = leaf_node_d[ str_p("PI") ]; + const_pi = leaf_node_d[ str_p("PI") ]; - fun_label = leaf_node_d[ ( lexeme_d[ "FUN" >> +digit_p ] ) ]; + const_gamma_mu = leaf_node_d[ str_p("GAMMA_MU") ]; - parameter = leaf_node_d[ ( lexeme_d[ "PAR" >> +digit_p ] ) ]; + fun_label = leaf_node_d[ ( lexeme_d[ "FUN" >> +digit_p ] ) ]; - map = leaf_node_d[ ( lexeme_d[ "MAP" >> +digit_p ] ) ]; + parameter = leaf_node_d[ ( lexeme_d[ "PAR" >> +digit_p ] ) ]; - function = str_p("COS") >> ch_p('(') >> expression >> ch_p(')') - | str_p("SIN") >> ch_p('(') >> expression >> ch_p(')') - | str_p("TAN") >> ch_p('(') >> expression >> ch_p(')') - | str_p("COSH") >> ch_p('(') >> expression >> ch_p(')') - | str_p("SINH") >> ch_p('(') >> expression >> ch_p(')') - | str_p("TANH") >> ch_p('(') >> expression >> ch_p(')') - | str_p("ACOS") >> ch_p('(') >> expression >> ch_p(')') - | str_p("ASIN") >> ch_p('(') >> expression >> ch_p(')') - | str_p("ATAN") >> ch_p('(') >> expression >> ch_p(')') - | str_p("ACOSH") >> ch_p('(') >> expression >> ch_p(')') - | str_p("ASINH") >> ch_p('(') >> expression >> ch_p(')') - | str_p("ATANH") >> ch_p('(') >> expression >> ch_p(')') - | str_p("LOG") >> ch_p('(') >> expression >> ch_p(')') - | str_p("LN") >> ch_p('(') >> expression >> ch_p(')') - | str_p("EXP") >> ch_p('(') >> expression >> ch_p(')') - ; + map = leaf_node_d[ ( lexeme_d[ "MAP" >> +digit_p ] ) ]; - factor = real - | const_pi - | parameter - | map - | function - | inner_node_d[ch_p('(') >> expression >> ch_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(')') + ; - term = factor >> - *( (root_node_d[ch_p('*')] >> factor) - | (root_node_d[ch_p('/')] >> factor) - ); + factor = real + | const_pi + | const_gamma_mu + | parameter + | map + | function + | inner_node_d[ch_p('(') >> expression >> ch_p(')')] + ; - expression = term >> - *( (root_node_d[ch_p('+')] >> term) - | (root_node_d[ch_p('-')] >> term) - ); + term = factor >> + *( (root_node_d[ch_p('*')] >> factor) + | (root_node_d[ch_p('/')] >> factor) + ); - assignment = (fun_label >> ch_p('=') >> expression); + 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); @@ -137,6 +142,7 @@ 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; diff --git a/src/tests/spirit/PFunction.cpp b/src/tests/spirit/PFunction.cpp index ec9530e8..b57bab1c 100644 --- a/src/tests/spirit/PFunction.cpp +++ b/src/tests/spirit/PFunction.cpp @@ -161,9 +161,9 @@ bool PFunction::CheckParameterAndMapInTree(iter_t const& i) fValid = false; } } else if (i->value.id() == PFunctionGrammar::functionID) { - assert(i->children.size() == 4); - // i: 'funcName', '(', 'expression', ')' - success = CheckParameterAndMapInTree(i->children.begin()+2); // thats the real stuff + assert(i->children.size() == 3); + // i: '(', 'expression', ')' + success = CheckParameterAndMapInTree(i->children.begin()+1); // thats the real stuff } else if (i->value.id() == PFunctionGrammar::factorID) { // i: real | parameter | map | function | expression assert(i->children.size() == 1); @@ -268,9 +268,8 @@ void PFunction::FillFuncEvalTree(iter_t const& i, PFuncTreeNode &node) // keep the id node.fID = PFunctionGrammar::functionID; // keep function tag - // i: 'funcName', '(', 'expression', ')' - iter_t it = i->children.begin(); - str = string(it->value.begin(), it->value.end()); // get string + // i: '(', 'expression', ')' + str = string(i->value.begin(), i->value.end()); // get string // cout << endl << ">> functionID: value = " << str; if (!strcmp(str.c_str(), "COS")) node.fFunctionTag = FUN_COS; @@ -308,8 +307,8 @@ void PFunction::FillFuncEvalTree(iter_t const& i, PFuncTreeNode &node) } // add node node.children.push_back(child); - // i: 'funcName', '(', 'expression', ')' - FillFuncEvalTree(i->children.begin()+2, node.children[0]); + // i: '(', 'expression', ')' + FillFuncEvalTree(i->children.begin()+1, node.children[0]); } else if (i->value.id() == PFunctionGrammar::factorID) { // cout << endl << ">> factorID"; // keep the id @@ -534,19 +533,16 @@ long PFunction::EvalTreeExpression(iter_t const& i) cout << endl << "-----"; fFuncString += string(i->value.begin(), i->value.end()); } else if (i->value.id() == PFunctionGrammar::functionID) { - assert(i->children.size() == 4); + assert(i->children.size() == 3); cout << endl << "functionID: children = " << i->children.size(); - iter_t it = i->children.begin(); - cout << endl << "functionID: value = " << string(it->value.begin(), it->value.end()); + cout << endl << "functionID: value = " << string(i->value.begin(), i->value.end()); cout << endl << "-----"; - // funcName, '(', expression, ')' + // '(', expression, ')' counter++; - fFuncString += string(it->value.begin(), it->value.end()); - if (termOp == 0) - fFuncString += "("; - EvalTreeExpression(i->children.begin()+2); // the real stuff - if (termOp == 0) - fFuncString += ")"; + fFuncString += string(i->value.begin(), i->value.end()); + fFuncString += "("; + EvalTreeExpression(i->children.begin()+1); // the real stuff + fFuncString += ")"; counter--; } else if (i->value.id() == PFunctionGrammar::factorID) { cout << endl << "factorID: children = " << i->children.size(); @@ -555,58 +551,50 @@ long PFunction::EvalTreeExpression(iter_t const& i) counter--; } else if (i->value.id() == PFunctionGrammar::termID) { cout << endl << "termID: children = " << i->children.size(); + counter++; + termOp++; if (*i->value.begin() == '*') { cout << endl << "termID: '*'"; assert(i->children.size() == 2); - counter++; - termOp++; EvalTreeExpression(i->children.begin()); fFuncString += " * "; EvalTreeExpression(i->children.begin()+1); - termOp--; - counter--; } else if (*i->value.begin() == '/') { cout << endl << "termID: '/'"; assert(i->children.size() == 2); - counter++; - termOp++; EvalTreeExpression(i->children.begin()); fFuncString += " / "; EvalTreeExpression(i->children.begin()+1); - termOp--; - counter--; } else { assert(0); } + termOp--; + counter--; } else if (i->value.id() == PFunctionGrammar::expressionID) { cout << endl << "expressionID: children = " << i->children.size(); + if (termOp > 0) + fFuncString += "("; if (*i->value.begin() == '+') { cout << endl << "expressionID: '+'"; assert(i->children.size() == 2); counter++; - if (termOp > 0) - fFuncString += "("; EvalTreeExpression(i->children.begin()); fFuncString += " + "; EvalTreeExpression(i->children.begin()+1); - if (termOp > 0) - fFuncString += ")"; counter--; } else if (*i->value.begin() == '-') { cout << endl << "expressionID: '-'"; assert(i->children.size() == 2); counter++; - if (termOp > 0) - fFuncString += "("; EvalTreeExpression(i->children.begin()); fFuncString += " - "; EvalTreeExpression(i->children.begin()+1); - if (termOp > 0) - fFuncString += ")"; counter--; } else { assert(0); } + if (termOp > 0) + fFuncString += ")"; } else if (i->value.id() == PFunctionGrammar::assignmentID) { cout << endl << "assignmentID: children = " << i->children.size(); assert(i->children.size() == 3); @@ -693,16 +681,15 @@ long PFunction::PrintTreeExpression(iter_t const& i) } } } else if (i->value.id() == PFunctionGrammar::functionID) { - // i: 'funcName', '(', 'expression', ')' - if (i->children.size() == 4) { + // i: '(', 'expression', ')' + str = string(i->value.begin(), i->value.end()); + cout << endl << ">> " << str; + if (i->children.size() == 3) { j = i->children.begin(); str = string(j->value.begin(), j->value.end()); cout << endl << ">> " << str; - j = i->children.begin()+1; - str = string(j->value.begin(), j->value.end()); - cout << endl << ">> " << str; - PrintTreeExpression(i->children.begin()+2); - j = i->children.begin()+3; + PrintTreeExpression(i->children.begin()+1); + j = i->children.begin()+2; str = string(j->value.begin(), j->value.end()); cout << endl << ">> " << str; } else { diff --git a/src/tests/spirit/PFunctionGrammar.h b/src/tests/spirit/PFunctionGrammar.h index efcfedd8..a442970f 100644 --- a/src/tests/spirit/PFunctionGrammar.h +++ b/src/tests/spirit/PFunctionGrammar.h @@ -35,7 +35,7 @@ #include using namespace std; -#define BOOST_SPIRIT_DEBUG +//#define BOOST_SPIRIT_DEBUG #include #include @@ -75,21 +75,21 @@ struct PFunctionGrammar : public grammar map = leaf_node_d[ ( lexeme_d[ "MAP" >> +digit_p ] ) ]; - function = str_p("COS") >> ch_p('(') >> expression >> ch_p(')') - | str_p("SIN") >> ch_p('(') >> expression >> ch_p(')') - | str_p("TAN") >> ch_p('(') >> expression >> ch_p(')') - | str_p("COSH") >> ch_p('(') >> expression >> ch_p(')') - | str_p("SINH") >> ch_p('(') >> expression >> ch_p(')') - | str_p("TANH") >> ch_p('(') >> expression >> ch_p(')') - | str_p("ACOS") >> ch_p('(') >> expression >> ch_p(')') - | str_p("ASIN") >> ch_p('(') >> expression >> ch_p(')') - | str_p("ATAN") >> ch_p('(') >> expression >> ch_p(')') - | str_p("ACOSH") >> ch_p('(') >> expression >> ch_p(')') - | str_p("ASINH") >> ch_p('(') >> expression >> ch_p(')') - | str_p("ATANH") >> ch_p('(') >> expression >> ch_p(')') - | str_p("LOG") >> ch_p('(') >> expression >> ch_p(')') - | str_p("LN") >> ch_p('(') >> expression >> ch_p(')') - | str_p("EXP") >> ch_p('(') >> expression >> ch_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(')') ; factor = real diff --git a/src/tests/spirit/fcnInput.txt b/src/tests/spirit/fcnInput.txt index b835cb07..36c485a7 100644 --- a/src/tests/spirit/fcnInput.txt +++ b/src/tests/spirit/fcnInput.txt @@ -18,7 +18,7 @@ PAR 1.0 2.1 3.5 -0.87 0.87 MAP 2 1 4 5 FUNCTIONS #fun0 = sin(par3/(par1+map2)) -fun1 = cos(par2) +fun1 = (sin(par1)*cos(par1)+((map1))) #fun0 = par1 + map3 * cos(cos(par2 - map1)) #fun8 = log(sin(par1)) + exp(-1.0*map2) #fun1 = par1 + map1 * (0.01355+par1*(2.1 - (-2.3 / 3.4)))