#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <cmath>
#include <algorithm>
//defines
#define space ' '
//disables any deprecation warning
#pragma warning(disable : 4996)
//usings
using std::vector;
using std::string;
using std::cout;
using std::endl;
long double nabs(long double dub) {
return -abs(dub);
}
string remove_char(string str, char c = space) {
str.erase(std::remove(str.begin(), str.end(), c), str.end());
return str;
}
long double parse(string str) {
return std::stold(str);
}
bool try_parse(string str) {
char* end = 0;
long double val = strtold(str.c_str(), &end);
return end != str.c_str() && val != HUGE_VALL && val != -HUGE_VALL;
}
char first_char(string str) {
return *str.c_str();
}
bool is_opr(string str) {
return first_char(str) == '&';
}
string &first_item(vector<string> vec) {
return vec[0];
}
vector<string> get_types(vector<string> vec) {
for (int i = 0; i < vec.size(); i++) {
string &s = vec[i];
bool doubly = try_parse(s);
bool amp = is_opr(s);
//if unknown
if (!doubly && !amp) {
s = "<unk> " + s;
continue;
}
//if operator
else if (!doubly && amp) {
s = "<opr> " + s;
continue;
}
//if number
else if (doubly && !amp) {
s = "<dub> " + s;
continue;
}
}
return vec;
}
long double interpretar_numero(string dub) {
if (dub.substr(0, 6).compare("<dub> ") != 0) {
throw "Não deu para interpretar como número " + dub;
}
return parse(dub.substr(6));
}
long double get_result(vector<string> vec) {
if (vec.at(0).compare("<opr> &sb") == 0 || vec.at(0).compare("<opr> &ad") == 0) {
vec.insert(vec.begin(), "<dub> 0");
}
long double val = interpretar_numero(vec.at(0));
for (int i = 1; i < vec.size(); i += 2) {
std::string op = vec.at(i);
if (vec.size() == i + 1) throw "Esperava um número antes do fim";
long double ot = interpretar_numero(vec.at(i + 1));
if (op.compare("<opr> &ad") == 0) {
val += ot;
} else if (op.compare("<opr> &sb") == 0) {
val -= ot;
} else if (op.compare("<opr> &mp") == 0) {
val *= ot;
} else if (op.compare("<opr> &dv") == 0) {
val /= ot;
} else {
throw "Esperava um operador";
}
}
return val;
}
vector<string> split(string s, const char c = space) {
string buff{ "" };
vector<string> v;
for (auto n : s) {
if (n != c) {
buff += n;
} else if (n == c && buff != "") {
v.push_back(buff);
buff = "";
}
}
if (buff != "") v.push_back(buff);
return v;
}
string simplify(string expr) {
string iexpr = expr;
for (int i = 0; i < iexpr.length(); i++) {
char& c = iexpr[i];
if (c == '+') {
iexpr.replace(i, 1, " &ad ");
} else if (c == '-') {
iexpr.replace(i, 1, " &sb ");
} else if (c == '*') {
iexpr.replace(i, 1, " &mp ");
} else if (c == '/') {
iexpr.replace(i, 1, " &dv ");
}
}
return iexpr;
}
int main() {
vector<string> sep_rep = get_types(split(simplify("-21 + 32 - 3 * 2")));
for (auto str : sep_rep) {
cout << str << endl;
}
try {
cout << "R: " << get_result(sep_rep) << endl;
} catch (const char *e) {
cout << "Erro: " << e;
} catch (string e) {
cout << "Erro: " << e;
}
std::cin.get();
return 0;
}