From 842463dc23c5388b002140bea6f3b4c465d7a01f Mon Sep 17 00:00:00 2001 From: nemu Date: Mon, 8 Mar 2010 10:43:46 +0000 Subject: [PATCH] added power capability [pow(base,exp)] to functions --- src/classes/PFunction.cpp | 57 ++++++++++++++++++++++++++-------- src/include/PFunction.h | 1 + src/include/PFunctionGrammar.h | 15 ++++++--- 3 files changed, 56 insertions(+), 17 deletions(-) diff --git a/src/classes/PFunction.cpp b/src/classes/PFunction.cpp index c323d6dd..7fd73216 100644 --- a/src/classes/PFunction.cpp +++ b/src/classes/PFunction.cpp @@ -258,6 +258,26 @@ void PFunction::FillFuncEvalTree(iter_t const& i, PFuncTreeNode &node) node.children.push_back(child); // i: '(', 'expression', ')' FillFuncEvalTree(i->children.begin()+1, node.children[0]); + } else if (i->value.id() == PFunctionGrammar::powerID) { + // keep the id + node.fID = PFunctionGrammar::powerID; + // keep function tag + str = string(i->value.begin(), i->value.end()); // get string + + if (!strcmp(str.c_str(), "POW")) + node.fFunctionTag = FUN_POW; + else { + cerr << endl << "**PANIC ERROR**: function " << str << " doesn't exist, but you never should have reached this point!"; + cerr << endl; + assert(0); + } + // i: '(', 'expression', ',', expression, ')' + // add node + node.children.push_back(child); + FillFuncEvalTree(i->children.begin()+1, node.children[0]); // base + // add node + node.children.push_back(child); + FillFuncEvalTree(i->children.begin()+3, node.children[1]); // exponent } else if (i->value.id() == PFunctionGrammar::factorID) { // cout << endl << ">> factorID"; // keep the id @@ -273,12 +293,6 @@ void PFunction::FillFuncEvalTree(iter_t const& i, PFuncTreeNode &node) node.fOperatorTag = OP_MUL; else node.fOperatorTag = OP_DIV; -/* -if (node.fOperatorTag == OP_MUL) - cout << endl << ">> termID: value = *"; -else - cout << endl << ">> termID: value = /"; -*/ // add child lhs node.children.push_back(child); FillFuncEvalTree(i->children.begin(), node.children[0]); @@ -293,12 +307,6 @@ else node.fOperatorTag = OP_ADD; else node.fOperatorTag = OP_SUB; -/* -if (node.fOperatorTag == OP_ADD) - cout << endl << ">> expressionID: value = +"; -else - cout << endl << ">> expressionID: value = -"; -*/ // add child lhs node.children.push_back(child); FillFuncEvalTree(i->children.begin(), node.children[0]); @@ -356,6 +364,11 @@ Bool_t PFunction::FindAndCheckMapAndParamRange(PFuncTreeNode &node, UInt_t mapSi return false; } else if (node.fID == PFunctionGrammar::functionID) { return FindAndCheckMapAndParamRange(node.children[0], mapSize, paramSize); + } else if (node.fID == PFunctionGrammar::powerID) { + if (FindAndCheckMapAndParamRange(node.children[0], mapSize, paramSize)) + return FindAndCheckMapAndParamRange(node.children[1], mapSize, paramSize); + else + return false; } else if (node.fID == PFunctionGrammar::factorID) { return FindAndCheckMapAndParamRange(node.children[0], mapSize, paramSize); } else if (node.fID == PFunctionGrammar::termID) { @@ -369,7 +382,8 @@ Bool_t PFunction::FindAndCheckMapAndParamRange(PFuncTreeNode &node, UInt_t mapSi else return false; } else { - cerr << endl << "**PANIC ERROR**: PFunction::FindAndCheckMapAndParamRange: you never should have reached this point!"; + cerr << endl << ">> **PANIC ERROR**: PFunction::FindAndCheckMapAndParamRange: you never should have reached this point!"; + cerr << endl << ">> node.fID = " << node.fID; cerr << endl; assert(0); } @@ -456,6 +470,14 @@ Double_t PFunction::EvalNode(PFuncTreeNode &node) cerr << endl; assert(0); } + } else if (node.fID == PFunctionGrammar::powerID) { + if (node.fFunctionTag == FUN_POW) { + return pow(EvalNode(node.children[0]), EvalNode(node.children[1])); + } else { + cerr << endl << "**PANIC ERROR**: PFunction::EvalNode: node.fID == PFunctionGrammar::powerID: you never should have reached this point!"; + cerr << endl; + assert(0); + } } else if (node.fID == PFunctionGrammar::factorID) { return EvalNode(node.children[0]); } else if (node.fID == PFunctionGrammar::termID) { @@ -569,6 +591,15 @@ void PFunction::EvalTreeForStringExpression(iter_t const& i) // '(', expression, ')' EvalTreeForStringExpression(i->children.begin()+1); // the real stuff fFuncString += ")"; + } else if (i->value.id() == PFunctionGrammar::powerID) { + assert(i->children.size() == 5); + fFuncString += string(i->value.begin(), i->value.end()).c_str(); // keep function name + fFuncString += "("; + // '(', expression, ',' expression, ')' + EvalTreeForStringExpression(i->children.begin()+1); // base expression + fFuncString += ","; + EvalTreeForStringExpression(i->children.begin()+3); // exponent expression + fFuncString += ")"; } else if (i->value.id() == PFunctionGrammar::factorID) { EvalTreeForStringExpression(i->children.begin()); } else if (i->value.id() == PFunctionGrammar::termID) { diff --git a/src/include/PFunction.h b/src/include/PFunction.h index 900cd592..0d522c56 100644 --- a/src/include/PFunction.h +++ b/src/include/PFunction.h @@ -70,6 +70,7 @@ #define FUN_LN 13 #define FUN_EXP 14 #define FUN_SQRT 15 +#define FUN_POW 16 //---------------------------------------------------------------------------- typedef struct func_tree_node { diff --git a/src/include/PFunctionGrammar.h b/src/include/PFunctionGrammar.h index cd4e2f46..cb76db0a 100644 --- a/src/include/PFunctionGrammar.h +++ b/src/include/PFunctionGrammar.h @@ -66,10 +66,11 @@ struct PFunctionGrammar : public grammar 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; + static const int powerID = 8; + static const int factorID = 9; + static const int termID = 10; + static const int expressionID = 11; + static const int assignmentID = 12; template struct definition @@ -108,12 +109,16 @@ struct PFunctionGrammar : public grammar | lexeme_d[ root_node_d[ str_p("SQRT") ] >> ch_p('(') ] >> expression >> ch_p(')') ; + power = lexeme_d[ root_node_d[ str_p("POW") ] >> ch_p('(') ] >> expression >> ch_p(',') >> expression >> ch_p(')') + ; + factor = real | const_pi | const_gamma_mu | parameter | map | function + | power | inner_node_d[ch_p('(') >> expression >> ch_p(')')] ; @@ -138,6 +143,7 @@ struct PFunctionGrammar : public grammar BOOST_SPIRIT_DEBUG_RULE(parameter); BOOST_SPIRIT_DEBUG_RULE(map); BOOST_SPIRIT_DEBUG_RULE(function); + BOOST_SPIRIT_DEBUG_RULE(power); BOOST_SPIRIT_DEBUG_RULE(factor); BOOST_SPIRIT_DEBUG_RULE(term); BOOST_SPIRIT_DEBUG_RULE(expression); @@ -149,6 +155,7 @@ struct PFunctionGrammar : public grammar rule, parser_tag > term; rule, parser_tag > factor; rule, parser_tag > function; + rule, parser_tag > power; rule, parser_tag > map; rule, parser_tag > parameter; rule, parser_tag > fun_label;