added power capability [pow(base,exp)] to functions

This commit is contained in:
nemu 2010-03-08 10:43:46 +00:00
parent 643dd1fa9d
commit 842463dc23
3 changed files with 56 additions and 17 deletions

View File

@ -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) {

View File

@ -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 {

View File

@ -66,10 +66,11 @@ struct PFunctionGrammar : public grammar<PFunctionGrammar>
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 <typename ScannerT>
struct definition
@ -108,12 +109,16 @@ struct PFunctionGrammar : public grammar<PFunctionGrammar>
| 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<PFunctionGrammar>
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<PFunctionGrammar>
rule<ScannerT, parser_context<>, parser_tag<termID> > term;
rule<ScannerT, parser_context<>, parser_tag<factorID> > factor;
rule<ScannerT, parser_context<>, parser_tag<functionID> > function;
rule<ScannerT, parser_context<>, parser_tag<powerID> > power;
rule<ScannerT, parser_context<>, parser_tag<mapID> > map;
rule<ScannerT, parser_context<>, parser_tag<parameterID> > parameter;
rule<ScannerT, parser_context<>, parser_tag<funLabelID> > fun_label;