/
xverizex
/
ximas
Обзор
Документация
Войти
/
xverizex
/
ximas
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/Equation.cpp
806 строк
27 KB
Dmitry
[+] Добавил тесты. Теперь отрицательные числа работают корректно.
17 июл 2026, 03:19
17 июл 2026, 03:19
d4b5e89
Код
Авторство
О чём код?
#include "Equation.h" #include "Token.h" #include <iostream> #include <filesystem> #include <fstream> #include <vector> #include <sstream> template <typename T> static T ato (std::string &buf, ximas::ModeCalcEquation mode) { switch (mode) { case ximas::ModeCalcEquation::DOUBLE: return atof (buf.c_str ()); case ximas::ModeCalcEquation::INT: return atol (buf.c_str ()); } return 0; } template <typename T> static void calc (int *a, int ia, char sym, T& sum, int sym_pos) { if (ia == 2) { switch (sym) { case '*': sum += a[0] * a[1]; break; case '+': sum += a[0] + a[1]; break; case '-': sum += a[0] - a[1]; break; case '/': sum += a[0] / a[1]; default: return; } } if (ia == 1) { switch (sym) { case '*': if (sym_pos == 1) { sum = a[0] * sum; } else { sum *= a[0]; } break; case '+': if (sym_pos == 1) { sum = a[0] + sum; } else { sum += a[0]; } break; case '-': if (sym_pos == 1) { sum = a[0] - sum; } else { sum -= a[0]; } break; case '/': if (sym_pos == 1) { sum = a[0] / sum; } else { sum /= a[0]; } break; default: return; } } return; } static int is_exp (char sym) { if ((sym == '*') || (sym == '+') || (sym == '-') || (sym == '/')) return 1; return 0; } static int is_add (char sym) { if ((sym == '+') || (sym == '-')) return 1; return 0; } static int is_mul (char sym) { if ((sym == '*') || (sym == '/')) return 1; return 0; } static bool isNum (std::string &val) { size_t sz = val.size (); for (size_t i = 0; i < sz; i++) { if ((val[i] >= '0') && (val[i] <= '9')) { continue; } return false; } return true; } template <typename T> static void parse_calc (std::vector<Token *>& arr, int& indx, T& sum, ximas::ModeCalcEquation modeEq, bool debug) { if (arr.size () > 0) { int a[2]; int ia = 0; int sym_pos = 0; char math_ = 0; bool is_first = true; bool is_new_math = false; int sz = arr.size (); int pos = 0; bool isMinus = false; while (arr[indx]->buf () == "-") { isMinus = !isMinus; indx++; } if (isNum (arr[indx]->buf ())) { indx++; } if ((indx == 0) && (arr[indx]->buf () != "(")) { indx = 1; } if (isNum (arr[indx]->buf ())) { indx++; } if (debug) { std::cout << "\tindx: " << indx << std::endl; } if (debug) { std::cout << "\tsum: " << sum << std::endl; } for (int k = indx; k < sz; k += 2) { if (arr[k]->type () == ximas::TokenType::END) { break; } sym_pos = 0; if (arr[k]->buf () == "(") { if (debug) { std::cout << "#0: " << std::endl; } int tmp = 0; int tmpk = k; k += 2; parse_calc (arr, k, tmp, modeEq, debug); if (debug) { std::cout << "\ttmp: " << tmp << std::endl; } sum += tmp; k -= 2; if (debug) { std::cout << "\tsum: " << tmp << std::endl; } } else if (arr[k]->buf () == ")") { if (debug) { std::cout << "#< " << std::endl; } indx = k + 1; return; } else if (((k + 1) < sz) && (arr[k + 1]->buf () == "(")) { if (debug) { std:: cout << "#1: " << std::endl; } int tmp = 0; int tmpk = k; k++; k += 2; parse_calc (arr, k, tmp, modeEq, debug); int max = k; if (debug) { std::cout << "tmp: " << tmp << "; k: " << k << std::endl; } ia = 0; if ((arr[k]->buf () == "*") || (arr[k]->buf () == "/")) { if (debug) { std::cout << " ##0: " << std::endl; } if (arr[k + 1]->buf () == "(") { if (debug) { std::cout << " ##1: " << std::endl; } ia = 0; #if 0 { a[ia++] = sum; char sym = arr[k]; math_ = sym; calc (a, ia, math_, sum, sym_pos); if (debug) { std::cout << "\t{sum: " << sum << "; tmp: " << tmp << "}" << std::endl; } #endif int f = k; k++; k += 2; int tmpp = 0; parse_calc (arr, k, tmpp, modeEq, debug); if (debug) { std::cout << "\tsum: " << sum << "; tmp: " << tmp << "; tmpp: " << tmpp << std::endl; } max = k; k = f; ia = 0; #if 0 a[ia++] = arr[k - 1] - '0'; char sym = arr[k]; math_ = sym; if (debug) { std::cout << "\ta[0]: " << a[0] << std::endl; } calc (a, ia, math_, sum, sym_pos); #else a[ia++] = tmpp; char sym = arr[k]->buf ()[0]; math_ = sym; if (debug) { std::cout << "\ta[0]: " << a[0] << std::endl; } calc (a, ia, math_, tmp, sym_pos); sum = tmp; #endif k += 2; if (debug) { std::cout << "\tsum 0: " << sum << std::endl; } k = max; } else { a[ia++] = ato<T> (arr[k + 1]->buf (), modeEq); char sym = arr[k]->buf ()[0]; math_ = sym; if (debug) { std::cout << "\ta[0]: " << a[0] << std::endl; } calc (a, ia, math_, tmp, sym_pos); k += 2; } if (debug) { std::cout << "\ttmp: " << tmp << std::endl; } } while ((arr[k]->buf () == "*") || (arr[k]->buf () == "/")) { if (debug) { std::cout << " ##1: " << std::endl; } ia = 0; a[ia++] = ato<T> (arr[k + 1]->buf (), modeEq); if (debug) { std::cout << "\ta[0]: " << a[0] << std::endl; } char sym = arr[k]->buf ()[0]; math_ = sym; calc (a, ia, math_, tmp, sym_pos); k += 2; if (debug) { std::cout << "\tsum: " << sum << "; tmp: " << tmp << std::endl; } sum = tmp; } max = k; k = tmpk; if (debug) { std::cout << "\ttmpk: " << tmpk << std::endl; } ia = 0; if (pos == 0) { if (debug) { std::cout << "\tpos == 0" << std::endl; } a[ia++] = ato<T> (arr[k - 1]->buf (), modeEq); char sym = arr[k]->buf ()[0]; math_ = sym; sym_pos = 1; if (debug) { std::cout << "\ta[0]: " << a[0] << "; tmp: " << tmp << std::endl; } calc (a, ia, math_, tmp, sym_pos); if (debug) { std::cout << "\tsum: " << sum << "; tmp: " << tmp << std::endl; } sum = tmp; } else { if (debug) { std::cout << "\tpos == 1" << std::endl; } a[ia++] = sum; if (debug) { std::cout << "\ta[0]: " << a[0] << "; tmp: " << tmp << std::endl; } char sym = arr[k]->buf ()[0]; math_ = sym; sym_pos = 1; calc (a, ia, math_, tmp, sym_pos); if (debug) { std::cout << "\tsum: " << sum << "; tmp: " << tmp << std::endl; } sum = tmp; } k = max - 2; pos = 1; } else if ((pos == 0) && ((k + 2) < sz) && (((arr[k]->buf () == "+") || (arr[k]->buf () == "-")) && ((arr[k + 2]->buf () == "*") || (arr[k + 2]->buf () == "/")))) { if (debug) { std::cout << "#2: " << std::endl; } pos = 1; int tmp = sum; ia = 0; sum = 0; int tmpk = k; int max = tmpk; k += 2; if ((arr[k]->buf () == "*") || (arr[k]->buf () == "/")) { ia = 0; if (arr[k + 1]->buf () == "(") { if (debug) { std::cout << "\tif (arr[k + 1]->buf () == '('" << std::endl; } int tmp = 0; int f = k; k++; k += 2; parse_calc (arr, k, tmp, modeEq, debug); sum += tmp; max = k; k = f; ia = 0; a[ia++] = ato<T> (arr[k - 1]->buf (), modeEq); char sym = arr[k]->buf ()[0]; math_ = sym; calc (a, ia, math_, sum, sym_pos); k += 2; k = max; } else { if (debug) { std::cout << "\tif buf () != '('" << std::endl; } ia = 0; a[ia++] = ato<T> (arr[k - 1]->buf (), modeEq); a[ia++] = ato<T> (arr[k + 1]->buf (), modeEq); char sym = arr[k]->buf ()[0]; math_ = sym; if (debug) { std::cout << "\ta0: " << a[0] << "; a[1]: " << a[1] << std::endl; } calc (a, ia, math_, sum, sym_pos); k += 2; if (debug) { std::cout << "\tsum: " << sum << "; k: " << k << std::endl; } } } while ((arr[k]->buf () == "*") || (arr[k]->buf () == "/")) { if (arr[k + 1]->buf () == "(") { int tmp = 0; int f = k; k++; k += 2; parse_calc (arr, k, tmp, modeEq, debug); sum += tmp; max = k; k = f; ia = 0; a[ia++] = ato<T> (arr[k - 1]->buf (), modeEq); char sym = arr[k]->buf ()[0]; math_ = sym; calc (a, ia, math_, sum, sym_pos); k += 2; k = max; } else { ia = 0; a[ia++] = ato<T> (arr[k + 1]->buf (), modeEq); char sym = arr[k]->buf ()[0]; math_ = sym; calc (a, ia, math_, sum, sym_pos); k += 2; } } k -= 2; int indxk = k; k = tmpk; ia = 0; a[ia++] = ato<T> (arr[k - 1]->buf (), modeEq); if (isMinus) a[0] = -a[0]; if (debug) { std::cout << "\tpost #2; a[0]: " << a[0] << std::endl; } char sym = arr[k]->buf ()[0]; math_ = sym; calc (a, ia, math_, sum, sym_pos); k = indxk; if (debug) { std::cout << "\tsum #2: " << sum << std::endl; } } else if (((k + 2) < sz) && (((arr[k]->buf () == "+") || (arr[k]->buf () == "-")) && ((arr[k + 2]->buf () == "*") || (arr[k + 2]->buf () == "/")))) { if (debug) { std::cout << "#3: " << std::endl; } { pos = 1; ia = 0; int tmpk = k; int max = tmpk; k += 2; int tmp = 0; if ((arr[k]->buf () == "*") || (arr[k]->buf () == "/")) { if (debug) { std::cout << " ##0: " << std::endl; } ia = 0; if (arr[k + 1]->buf () == "(") { if (debug) { std::cout << " ##1: " << std::endl; } int f = k; k++; k += 2; parse_calc (arr, k, tmp, modeEq, debug); if (debug) { std::cout << "\tsum: " << sum << "; tmp: " << tmp << std::endl; } sum += tmp; if (debug) { std::cout << "\tsumr: " << sum << std::endl; } max = k; k = f; ia = 0; a[ia++] = ato<T> (arr[k - 1]->buf (), modeEq); char sym = arr[k]->buf ()[0]; math_ = sym; if (debug) { std::cout << "\ta[0]: " << a[0] << std::endl; } calc (a, ia, math_, sum, sym_pos); k += 2; if (debug) { std::cout << "\tsum 0: " << sum << std::endl; } k = max; } else { if (debug) { std::cout << " ##2: " << std::endl; } ia = 0; a[ia++] = ato<T> (arr[k - 1]->buf (), modeEq); a[ia++] = ato<T> (arr[k + 1]->buf (), modeEq); char sym = arr[k]->buf ()[0]; math_ = sym; if (debug) { std::cout << "\ta[0]: " << a[0] << "; a[1]: " << a[1] << "; sum: " << sum << std::endl; } calc (a, ia, math_, tmp, sym_pos); k += 2; if (debug) { std::cout << "\tsum 1: " << sum << "; tmp: " << tmp << std::endl; } } } while ((arr[k]->buf () == "*") || (arr[k]->buf () == "/")) { if (debug) { std::cout << " ##3: " << std::endl; } if (arr[k + 1]->buf () == "(") { if (debug) { std::cout << " ##4: " << std::endl; } int tmp0 = 0; int f = k; k++; k += 2; parse_calc (arr, k, tmp0, modeEq, debug); if (debug) { std::cout << "\tsum: " << sum << "; tmp: " << tmp << "; tmp0: " << tmp0 << std::endl; } //sum += tmp; if (debug) { std::cout << "\tsum 2: " << sum << std::endl; } max = k; k = f; ia = 0; a[ia++] = tmp; char sym = arr[k]->buf ()[0]; math_ = sym; sym_pos = 1; if (debug) { std::cout << "\ta[0]: " << a[0] << std::endl; } calc (a, ia, math_, tmp0, sym_pos); k += 2; k = max; if (debug) { std::cout << "\tsum: " << sum << "; tmp: " << tmp << "; tmp0: " << tmp0 << std::endl; } tmp = tmp0; if (debug) { std::cout << "\tsum: " << sum << "; tmp: " << tmp << "; k: " << k << std::endl; } } else { if (debug) { std::cout << " ##5: " << std::endl; } ia = 0; a[ia++] = ato<T> (arr[k + 1]->buf (), modeEq); char sym = arr[k]->buf ()[0]; math_ = sym; if (debug) { std::cout << "\ta[0]: " << a[0] << std::endl; } calc (a, ia, math_, tmp, sym_pos); if (debug) { std::cout << "\tsum: " << sum << "; tmp: " << tmp << std::endl; } k += 2; } } k -= 2; if (debug) { std::cout << " ##6: " << std::endl; } int indxk = k; k = tmpk; if (debug) { std::cout << "\ttmpk: " << tmpk << std::endl; } ia = 0; a[ia++] = sum; char sym = arr[k]->buf ()[0]; math_ = sym; if (debug) { std::cout << "\ta[0]: " << a[0] << std::endl; } if (debug) { std::cout << "\ttmp: " << tmp << std::endl; } sym_pos = 1; calc (a, ia, math_, tmp, sym_pos); if (debug) { std::cout << "\tsum: " << sum << "; tmp: " << tmp << std::endl; } k = indxk; sum = tmp; if (debug) { std::cout << "\tsum: " << sum << std::endl; } } } else if ((pos == 0) && ((k + 1) < sz) && (is_exp (arr[k]->buf ()[0]) && (is_exp (arr[k + 1]->buf ()[0])))) { if (debug) { std::cout << "#4: " << std::endl; } pos = 1; if (debug) { std::cout << "\tk: " << arr[k]->buf () << "; " << arr[k + 1]->buf () << std::endl; } if ((is_add (arr[k]->buf ()[0]) || is_mul (arr[k]->buf ()[0])) && (arr[k + 1]->buf () == "-")) { bool isMinusSecond = true; int l = k + 2; while ((arr[l]->type () != ximas::TokenType::END) && (arr[l]->buf () == "-")) { isMinusSecond = !isMinusSecond; l++; } int k0 = k - 1; int k1 = l; pos = 1; ia = 0; if (debug) { std::cout << "\tarr[k1]->buf() == " << arr[k1]->buf () << std::endl; } if (arr[k1]->buf () == "(") { k1 += 2; int tmpp = 0; parse_calc (arr, k1, tmpp, modeEq, debug); a[ia++] = ato<T> (arr[k0]->buf (), modeEq); a[ia++] = tmpp; } else { a[ia++] = ato<T> (arr[k0]->buf (), modeEq); a[ia++] = ato<T> (arr[k1]->buf (), modeEq); } if (isMinus) { a[0] = -a[0]; } if (isMinusSecond) { a[1] = -a[1]; } if (debug) { std::cout << "\t" << a[0] << std::endl; std::cout << "\t" << a[1] << std::endl; } char sym = arr[k]->buf ()[0]; math_ = sym; calc (a, ia, math_, sum, sym_pos); k = k1; if (debug) { std::cout << "\t" << "sum: " << sum << "; k: " << k << std::endl; } } else if (is_add (arr[k]->buf ()[0]) && is_mul (arr[k + 2]->buf ()[0])) { int tmp = sum; ia = 0; int tmpk = k; k += 2; while ((arr[k]->buf () == "*") || (arr[k]->buf () == "/")) { ia = 0; a[ia++] = ato<T> (arr[k + 1]->buf (), modeEq); char sym = arr[k]->buf ()[0]; math_ = sym; calc (a, ia, math_, sum, sym_pos); k += 2; } k -= 2; //sum += tmp; int indxk = k; k = tmpk; ia = 0; a[ia++] = ato<T> (arr[k - 1]->buf (), modeEq); char sym = arr[k]->buf ()[0]; math_ = sym; sym_pos = 1; calc (a, ia, math_, sum, sym_pos); k = indxk; } else { ia = 0; a[ia++] = ato<T> (arr[k - 1]->buf (), modeEq); char sym = arr[k]->buf ()[0]; math_ = sym; calc (a, ia, math_, sum, sym_pos); k -= 1; } } else if (pos == 0) { if (debug) { std::cout << "#5: " << std::endl; } pos = 1; ia = 0; a[ia++] = ato<T> (arr[k - 1]->buf (), modeEq); a[ia++] = ato<T> (arr[k + 1]->buf (), modeEq); if (debug) { std::cout << "\t" << a[0] << std::endl; std::cout << "\t" << a[1] << std::endl; } char sym = arr[k]->buf ()[0]; math_ = sym; calc (a, ia, math_, sum, sym_pos); if (debug) { std::cout << "\t" << "sum: " << sum << "; k: " << k << std::endl; } } else { if (debug) { std::cout << "#6: " << std::endl; } ia = 0; a[ia++] = ato<T> (arr[k + 1]->buf (), modeEq); if (debug) { std::cout << "\ta[0]: " << a[0] << "; arr[k + 1]: " << arr[k + 1]->buf () << std::endl; } char sym = arr[k]->buf ()[0]; math_ = sym; calc (a, ia, math_, sum, sym_pos); if (debug) { std::cout << "\tsum: " << sum << "; k: " << k << std::endl; } } pos = 1; //std::cout << sum; } //calc (a, ia, math_, sum, sym_pos); //std::cout << sum; } } template <typename T> T parse_equation (std::vector<Token *> &buf, ximas::ModeCalcEquation modeEq, bool debug) { T sum = 0; int indx = 0; parse_calc<T> (buf, indx, sum, modeEq, debug); return sum; } static void transformToMinusValue (std::vector<Token *> &token) { std::vector<Token *> newToken; size_t sz = token.size (); #if 0 for (size_t i = 0; i < sz; i++) { if (token[i]->buf () == "-") } #endif } void calcOneLine (std::vector<Token *> &token, ximas::ModeCalcEquation modeEq, ximas::ModePrint modePn, std::string &output, bool debug) { double retdd; int64_t retd; std::stringstream str; transformToMinusValue (token); switch (modeEq) { case ximas::ModeCalcEquation::INT: retd = parse_equation<int64_t>(token, modeEq, debug); str << retd; break; } output = str.str (); }