📄 calcengine.cpp
字号:
#include "calcengine.h"#include <cctype>#include <cmath>#include <algorithm>CalculatorEngine::FunctionMapType CalculatorEngine::__funcTable;void CalculatorEngine::buildFunctionTable(){ __funcTable["sin"] = &Function::Sin; __funcTable["cos"] = &Function::Cos; __funcTable["tan"] = &Function::Tan; __funcTable["asin"] = &Function::Asin; __funcTable["acos"] = &Function::Acos; __funcTable["atan"] = &Function::Atan; __funcTable["sinh"] = &Function::Sinh; __funcTable["cosh"] = &Function::Cosh; __funcTable["tanh"] = &Function::Tanh; __funcTable["asinh"] = &Function::Asinh; __funcTable["acosh"] = &Function::Acosh; __funcTable["atanh"] = &Function::Atanh; __funcTable["exp"] = &Function::Exp; __funcTable["ln"] = &Function::Ln; __funcTable["log"] = &Function::Log; __funcTable["sqrt"] = &Function::Sqrt; __funcTable["fct"] = &Function::Fct;}CalculatorEngine::CalculatorEngine(){ __token = PRINT; __number = 0; __table["pi"] = Pi; __table["PI"] = Pi; __table["e"] = E; __inStream.str(""); buildFunctionTable();}void CalculatorEngine::pushIdentifier(const std::string& name, const ValueType& value){ if (name == std::string("pi") || name == std::string("Pi") || name == std::string("e")) throw InvalidAssignment(); __table[name] = value;}void CalculatorEngine::setRDState(CalculatorEngine::RDState s){ __func.__state = s;}void CalculatorEngine::setExpression(const std::string& expr){ __inStream.clear(); __inStream.str(expr);}ValueType CalculatorEngine::calculate(){ ValueType result; checkParenthesis(); while (__inStream) { getToken(); if (__token == END) break; if (__token == PRINT) continue; result = expr(false); } if (result >= Maximum) throw TooLarge(); return result;}ValueType CalculatorEngine::expr(bool get){ ValueType left = term1(get); for (;;) switch (__token) { case PLUS: left += term1(true); break; case MINUS: left -= term1(true); break; default: return left; }}ValueType CalculatorEngine::term1(bool get){ ValueType left = term2(get); for (;;) switch (__token) { case MUL: left *= term2(true); break; case DIV: if (ValueType d = term2(true)) { // nonzero left /= d; break; } throw ZeroDivide(); break; case MOD: if (ValueType d = term2(true)) { left = (long long)(left) % (long long)(d); break; } throw ZeroDivide(); break; default: return left; }}ValueType CalculatorEngine::term2(bool get){ ValueType left = prim(get); for (;;) switch (__token) { case POW: { ValueType e = expr(true); if ((left == 0 && e <= 0) || (left < 0 && floor(e) != e)) throw PowerError(); left = pow(left, e); break; } default: return left; }}ValueType CalculatorEngine::prim(bool get){ if (get) getToken(); switch (__token) { case NUMBER: { ValueType v = __number; getToken(); if (__token == NAME) { if (isFunction()) return v * unaryFunction(); else { getToken(); return v * __table[__string]; } } return v; } case NAME: { if (isFunction()) { ValueType v = unaryFunction(); return v; } else { ValueType& v = __table[__string]; getToken(); if (__token == ASSIGN) { if (__string == std::string("pi") || __string == std::string("PI") || __string == std::string("e")) throw InvalidAssignment(); v = expr(true); } return v; } } case MINUS: return -prim(true); case LP: { ValueType e = expr(true); if (__token != RP) throw RightParenMismatch(); getToken(); // eat ')' return e; } default: throw PrimaryMissing(); return 1; }} void CalculatorEngine::getToken(){ char ch; do { // skip whitespace except '\n' if (!__inStream.get(ch)) { __token == END; return; } } while (ch != '\n' && isspace(ch)); switch (ch) { case ';': case '\n': __token = PRINT; break; case '+': case '-': case '*': case '/': case '%': case '^': case '(': case ')': case '=': __token = Token(ch); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '.': __inStream.putback(ch); __inStream >> __number; __token = NUMBER; break; default: // NAME, NAME=, or error if (isalpha(ch)) { __string = ch; while (__inStream.get(ch) && isalnum(ch)) __string.push_back(ch); __inStream.putback(ch); __token = NAME; break; } __token = PRINT; throw BadToken(); }}bool CalculatorEngine::isFunction() const{ if (__funcTable.find(__string) != __funcTable.end()) return true; else return false;}ValueType CalculatorEngine::unaryFunction(){ std::string funcName = __string; getToken(); if (__token != LP) throw ParenMissing(__string.c_str()); ValueType v = expr(true); if (__token != RP) throw RightParenMismatch(); getToken(); return (__func.*__funcTable[funcName])(v);}void CalculatorEngine::checkParenthesis(){ std::string expression = __inStream.str(); int numLP = std::count(expression.begin(), expression.end(), '('); int numRP = std::count(expression.begin(), expression.end(), ')'); if (numLP < numRP) throw LeftParenMismatch(); else if (numRP < numLP) throw RightParenMismatch();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -