flScalar InfixToPostfix::evaluate(const std::string postfix, const std::map<std::string, flScalar>* variables) const { std::stack<flScalar> stack; std::stringstream ss(postfix); std::string token; while (ss >> token) { if (isOperand(token)) { if (isNumeric(token)) { stack.push(atof(token.c_str())); } else { if (!variables) { throw FuzzyException(FL_AT, "Impossible to compute operand <" + token + "> because no map was supplied"); } std::map<std::string, flScalar>::const_iterator it = variables->find(token); if (it == variables->end()) { throw FuzzyException(FL_AT, "Operand <" + token + "> not found in map"); } stack.push(it->second); } } else if (isOperator(token)) { if (isUnaryOperator(token)) { if (stack.empty()) { throw FuzzyException(FL_AT, "Error evaluating postfix expression <" + postfix + ">"); } flScalar a = stack.top(); stack.pop(); stack.push(compute(token, a, 0)); } else { if (stack.size() < 2) { throw FuzzyException(FL_AT, "Error evaluating postfix expression <" + postfix + ">"); } flScalar b = stack.top(); stack.pop(); flScalar a = stack.top(); stack.pop(); stack.push(compute(token, a, b)); } } } if (stack.size() == 1){ return stack.top(); } throw FuzzyException(FL_AT, "Error evaluating postfix expression <" + postfix + ">"); }
flScalar InfixToPostfix::compute(const std::string& op, flScalar a, flScalar b) const { if (op == "!") { return !(bool)a; } if (op == "and") { return (bool)a && (bool)b; } if (op == "or") { return (bool)a || (bool)b; } if (op == "+") { return a + b; } if (op == "-") { return a - b; } if (op == "*") { return a * b; } if (op == "/") { return a / b; } if (op == "%") { return (long) a % (long) b; } if (op == "^") { return pow(a, b); } if (op == "sin") { return sin(a); } if (op == "cos") { return cos(a); } if (op == "tan") { return tan(a); } if (op == "sinh") { return sinh(a); } if (op == "cosh") { return cosh(a); } if (op == "tanh") { return tanh(a); } throw FuzzyException(FL_AT, "Operator <" + op + "> not defined"); }
void FuzzyException::Assert(const std::string& file, int line, const std::string& function, bool assert, const std::string message) { if (!assert) { throw FuzzyException(file, line, function, message); } }