#include <string>
#include <vector>
#include <sstream>
#include <cctype>
#include <unordered_map>
#include <iostream>
#include <iomanip>
#include <stdexcept>
struct token {
std::string text;
enum tok_type {type_none,
type_integer,
type_double,
type_add,
type_sub,
type_mul,
type_div,
type_mod,
type_oparen,
type_cparen,
type_string,
} type;
int line;
int off;
token(std::string te, tok_type ty, int l, int o)
:text(te), type(ty), line(l), off(o)
{}
};
void error(const char* message, const token& found)
{
std::stringstream ss;
ss << message;
ss << " at line " << found.line << " character " << found.off;
ss << " found \"" << found.text << "\".";
throw std::runtime_error(ss.str());
}
token get_next_token(std::istream& str, int& line, int& off) {
int c = str.get();
++off;
while(std::isspace(c)) {
if (c=='\n') {++line; off=0;};
c = str.get();
++off;
}
switch (c) {
case EOF: return token("",token::type_none, line, off);
case '+': return token("+",token::type_add, line, off);
case '-': return token("-",token::type_sub, line, off);
case '*': return token("*",token::type_mul, line, off);
case '/': return token("/",token::type_div, line, off);
case '%': return token("/",token::type_mod, line, off);
case '(': return token("(",token::type_oparen, line, off);
case ')': return token(")",token::type_cparen, line, off);
case '0': case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
{
token t("",token::type_integer, line, off);
t.text.push_back(char(c));
int n = str.peek();
while(n>='0' && n<='9') {
n = str.get();
++off;
t.text.push_back(char(n));
n = str.peek();
}
if (n=='.') {
t.type = token::type_double;
n = str.get();
++off;
t.text.push_back(char(n));
n = str.peek();
while(n>='0' && n<='9') {
n = str.get();
++off;
t.text.push_back(char(n));
n = str.peek();
}
}
return t;
}
default:
token t("",token::type_string, line, off);
t.text.push_back(char(c));
if (!std::isalnum(c) && c!='_')
error("invalid character", t);
int n = str.peek();
while(std::isalnum(n) || n=='_') {
++off;
n = str.get();
t.text.push_back(char(n));
n = str.peek();
}
return t;
}
}
std::istream& operator>>(std::istream& str, std::vector<token>& r) {
int line=0;
int off=0;
r.clear();
do {
r.push_back(get_next_token(str, line, off));
} while(r.back().type);
return str;
}
typedef std::vector<token>::const_iterator token_iter;
typedef std::unordered_map<std::string, double> variable_map;
double do_term(token_iter& next, const variable_map& vars);
double do_value(token_iter& next, const variable_map& vars) {
if (next->type==token::type_none) error("Expected value", *next);
if (next->type == token::type_string) {
auto it = vars.find(next->text);
if (it == vars.end()) error("Unknown variable name", *next);
++next;
return it->second;
} else if(next->type == token::type_integer || next->type == token::type_double) {
std::stringstream ss(next->text);
double r;
ss >> r;
++next;
return r;
} else if (next->type == token::type_oparen) {
double r = do_term(++next, vars);
if (next->type != token::type_cparen) error("expected closing param", *next);
++next;
return r;
} else error("Expected value", *next); return 0.0;
}
double do_factor(token_iter& next, const variable_map& vars) {
double lhs = do_value(next, vars);
while(next->type == token::type_mul
|| next->type == token::type_div
|| next->type == token::type_mod)
{
token::tok_type op = next->type;
double rhs = do_value(++next, vars);
switch(op) {
case token::type_mul:
lhs *= rhs;
break;
case token::type_div:
if (rhs == 0) error("division by zero", *next);
lhs /= rhs;
break;
case token::type_mod:
if (rhs == 0) error("modulo by zero", *next);
lhs /= rhs;
break;
default: error("parser error", *next);
}
}
return lhs;
}
double do_term(token_iter& next, const variable_map& vars) {
double lhs = do_factor(next, vars);
while(next->type == token::type_add
|| next->type == token::type_sub)
{
token::tok_type op = next->type;
double rhs = do_factor(++next, vars);
switch(op) {
case token::type_add: lhs += rhs; break;
case token::type_sub: lhs -= rhs; break;
default: error("parser error", *next);
}
}
return lhs;
}
int main() {
try {
variable_map vars;
vars["ar"] = 3.14159;
vars["var"] = -.5;
std::vector<token> tokens;
//std::cout << "goal:\n87635+23754*ar+ar*var*0.895+(ar-var)+ar*ar+var*var =162272.684176\n";
//std::cout << "input:\n";
std::cin >> tokens;
if (tokens.empty())
throw std::runtime_error("failed to read any tokens!");
token_iter it = tokens.begin();
double r = do_term(it, vars);
if (it != tokens.end()-1)
error("parser error", *it);
std::cout << std::setprecision(14) << r;
} catch(const std::exception& rhs) {
std::cerr << rhs.what();
}
return 0;
}
I2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPHNzdHJlYW0+CiNpbmNsdWRlIDxjY3R5cGU+CiNpbmNsdWRlIDx1bm9yZGVyZWRfbWFwPgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDxpb21hbmlwPgojaW5jbHVkZSA8c3RkZXhjZXB0PgogCnN0cnVjdCB0b2tlbiB7CiAgICBzdGQ6OnN0cmluZyB0ZXh0OwogICAgZW51bSB0b2tfdHlwZSB7dHlwZV9ub25lLAogICAgICAgICAgICAgICAgICAgdHlwZV9pbnRlZ2VyLCAKICAgICAgICAgICAgICAgICAgIHR5cGVfZG91YmxlLCAKICAgICAgICAgICAgICAgICAgIHR5cGVfYWRkLCAKICAgICAgICAgICAgICAgICAgIHR5cGVfc3ViLCAKICAgICAgICAgICAgICAgICAgIHR5cGVfbXVsLCAKICAgICAgICAgICAgICAgICAgIHR5cGVfZGl2LCAKICAgICAgICAgICAgICAgICAgIHR5cGVfbW9kLCAKICAgICAgICAgICAgICAgICAgIHR5cGVfb3BhcmVuLCAKICAgICAgICAgICAgICAgICAgIHR5cGVfY3BhcmVuLAogICAgICAgICAgICAgICAgICAgdHlwZV9zdHJpbmcsCiAgICB9IHR5cGU7CiAgICBpbnQgbGluZTsKICAgIGludCBvZmY7CiAgICB0b2tlbihzdGQ6OnN0cmluZyB0ZSwgdG9rX3R5cGUgdHksIGludCBsLCBpbnQgbykKICAgICAgICA6dGV4dCh0ZSksIHR5cGUodHkpLCBsaW5lKGwpLCBvZmYobykKICAgIHt9Cn07CiAKdm9pZCBlcnJvcihjb25zdCBjaGFyKiBtZXNzYWdlLCBjb25zdCB0b2tlbiYgZm91bmQpCnsKICAgIHN0ZDo6c3RyaW5nc3RyZWFtIHNzOwogICAgc3MgPDwgbWVzc2FnZTsKICAgIHNzIDw8ICIgYXQgbGluZSAiIDw8IGZvdW5kLmxpbmUgPDwgIiBjaGFyYWN0ZXIgIiA8PCBmb3VuZC5vZmY7CiAgICBzcyA8PCAiIGZvdW5kIFwiIiA8PCBmb3VuZC50ZXh0IDw8ICJcIi4iOwogICAgdGhyb3cgc3RkOjpydW50aW1lX2Vycm9yKHNzLnN0cigpKTsKfQogCnRva2VuIGdldF9uZXh0X3Rva2VuKHN0ZDo6aXN0cmVhbSYgc3RyLCBpbnQmIGxpbmUsIGludCYgb2ZmKSB7CiAgICBpbnQgYyA9IHN0ci5nZXQoKTsKICAgICsrb2ZmOwogICAgd2hpbGUoc3RkOjppc3NwYWNlKGMpKSB7CiAgICAgICAgaWYgKGM9PSdcbicpIHsrK2xpbmU7IG9mZj0wO307ICAgICAgICAKICAgICAgICBjID0gc3RyLmdldCgpOwogICAgICAgICsrb2ZmOwogICAgfQogICAgc3dpdGNoIChjKSB7CiAgICBjYXNlIEVPRjogcmV0dXJuIHRva2VuKCIiLHRva2VuOjp0eXBlX25vbmUsIGxpbmUsIG9mZik7CiAgICBjYXNlICcrJzogcmV0dXJuIHRva2VuKCIrIix0b2tlbjo6dHlwZV9hZGQsIGxpbmUsIG9mZik7CiAgICBjYXNlICctJzogcmV0dXJuIHRva2VuKCItIix0b2tlbjo6dHlwZV9zdWIsIGxpbmUsIG9mZik7CiAgICBjYXNlICcqJzogcmV0dXJuIHRva2VuKCIqIix0b2tlbjo6dHlwZV9tdWwsIGxpbmUsIG9mZik7CiAgICBjYXNlICcvJzogcmV0dXJuIHRva2VuKCIvIix0b2tlbjo6dHlwZV9kaXYsIGxpbmUsIG9mZik7CiAgICBjYXNlICclJzogcmV0dXJuIHRva2VuKCIvIix0b2tlbjo6dHlwZV9tb2QsIGxpbmUsIG9mZik7CiAgICBjYXNlICcoJzogcmV0dXJuIHRva2VuKCIoIix0b2tlbjo6dHlwZV9vcGFyZW4sIGxpbmUsIG9mZik7CiAgICBjYXNlICcpJzogcmV0dXJuIHRva2VuKCIpIix0b2tlbjo6dHlwZV9jcGFyZW4sIGxpbmUsIG9mZik7CiAgICBjYXNlICcwJzogY2FzZSAnMSc6Y2FzZSAnMic6Y2FzZSAnMyc6Y2FzZSAnNCc6Y2FzZSAnNSc6Y2FzZSAnNic6Y2FzZSAnNyc6Y2FzZSAnOCc6Y2FzZSAnOSc6CiAgICB7CiAgICAgICAgdG9rZW4gdCgiIix0b2tlbjo6dHlwZV9pbnRlZ2VyLCBsaW5lLCBvZmYpOwogICAgICAgIHQudGV4dC5wdXNoX2JhY2soY2hhcihjKSk7CiAgICAgICAgaW50IG4gPSBzdHIucGVlaygpOwogICAgICAgIHdoaWxlKG4+PScwJyAmJiBuPD0nOScpIHsKICAgICAgICAgICAgbiA9IHN0ci5nZXQoKTsKICAgICAgICAgICAgKytvZmY7CiAgICAgICAgICAgIHQudGV4dC5wdXNoX2JhY2soY2hhcihuKSk7CiAgICAgICAgICAgIG4gPSBzdHIucGVlaygpOwogICAgICAgIH0KICAgICAgICBpZiAobj09Jy4nKSB7CiAgICAgICAgICAgIHQudHlwZSA9IHRva2VuOjp0eXBlX2RvdWJsZTsKICAgICAgICAgICAgbiA9IHN0ci5nZXQoKTsKICAgICAgICAgICAgKytvZmY7CiAgICAgICAgICAgIHQudGV4dC5wdXNoX2JhY2soY2hhcihuKSk7CiAgICAgICAgICAgIG4gPSBzdHIucGVlaygpOwogICAgICAgICAgICB3aGlsZShuPj0nMCcgJiYgbjw9JzknKSB7CiAgICAgICAgICAgICAgICBuID0gc3RyLmdldCgpOwogICAgICAgICAgICAgICAgKytvZmY7CiAgICAgICAgICAgICAgICB0LnRleHQucHVzaF9iYWNrKGNoYXIobikpOwogICAgICAgICAgICAgICAgbiA9IHN0ci5wZWVrKCk7CiAgICAgICAgICAgIH0gICAgICAgICAgICAKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHQ7CiAgICB9CiAgICBkZWZhdWx0OiAKICAgICAgICB0b2tlbiB0KCIiLHRva2VuOjp0eXBlX3N0cmluZywgbGluZSwgb2ZmKTsKICAgICAgICB0LnRleHQucHVzaF9iYWNrKGNoYXIoYykpOwogICAgICAgIGlmICghc3RkOjppc2FsbnVtKGMpICYmIGMhPSdfJykgCiAgICAgICAgICAgIGVycm9yKCJpbnZhbGlkIGNoYXJhY3RlciIsIHQpOwogICAgICAgIGludCBuID0gc3RyLnBlZWsoKTsKICAgICAgICB3aGlsZShzdGQ6OmlzYWxudW0obikgfHwgbj09J18nKSB7CiAgICAgICAgICAgICsrb2ZmOwogICAgICAgICAgICBuID0gc3RyLmdldCgpOwogICAgICAgICAgICB0LnRleHQucHVzaF9iYWNrKGNoYXIobikpOwogICAgICAgICAgICBuID0gc3RyLnBlZWsoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHQ7CiAgICB9ICAgIAp9CiAKc3RkOjppc3RyZWFtJiBvcGVyYXRvcj4+KHN0ZDo6aXN0cmVhbSYgc3RyLCBzdGQ6OnZlY3Rvcjx0b2tlbj4mIHIpIHsKICAgIGludCBsaW5lPTA7CiAgICBpbnQgb2ZmPTA7CiAgICByLmNsZWFyKCk7CiAgICBkbyB7CiAgICAgICAgci5wdXNoX2JhY2soZ2V0X25leHRfdG9rZW4oc3RyLCBsaW5lLCBvZmYpKTsKICAgIH0gd2hpbGUoci5iYWNrKCkudHlwZSk7CiAgICByZXR1cm4gc3RyOwp9CiAKdHlwZWRlZiBzdGQ6OnZlY3Rvcjx0b2tlbj46OmNvbnN0X2l0ZXJhdG9yIHRva2VuX2l0ZXI7CnR5cGVkZWYgc3RkOjp1bm9yZGVyZWRfbWFwPHN0ZDo6c3RyaW5nLCBkb3VibGU+IHZhcmlhYmxlX21hcDsKZG91YmxlIGRvX3Rlcm0odG9rZW5faXRlciYgbmV4dCwgY29uc3QgdmFyaWFibGVfbWFwJiB2YXJzKTsKCmRvdWJsZSBkb192YWx1ZSh0b2tlbl9pdGVyJiBuZXh0LCBjb25zdCB2YXJpYWJsZV9tYXAmIHZhcnMpIHsKICAgIGlmIChuZXh0LT50eXBlPT10b2tlbjo6dHlwZV9ub25lKSBlcnJvcigiRXhwZWN0ZWQgdmFsdWUiLCAqbmV4dCk7CiAgICBpZiAobmV4dC0+dHlwZSA9PSB0b2tlbjo6dHlwZV9zdHJpbmcpIHsKICAgICAgICBhdXRvIGl0ID0gdmFycy5maW5kKG5leHQtPnRleHQpOwogICAgICAgIGlmIChpdCA9PSB2YXJzLmVuZCgpKSBlcnJvcigiVW5rbm93biB2YXJpYWJsZSBuYW1lIiwgKm5leHQpOwogICAgICAgICsrbmV4dDsKICAgICAgICByZXR1cm4gaXQtPnNlY29uZDsKICAgIH0gZWxzZSBpZihuZXh0LT50eXBlID09IHRva2VuOjp0eXBlX2ludGVnZXIgfHwgbmV4dC0+dHlwZSA9PSAgdG9rZW46OnR5cGVfZG91YmxlKSB7CiAgICAgICAgc3RkOjpzdHJpbmdzdHJlYW0gc3MobmV4dC0+dGV4dCk7CiAgICAgICAgZG91YmxlIHI7CiAgICAgICAgc3MgPj4gcjsKICAgICAgICArK25leHQ7CiAgICAgICAgcmV0dXJuIHI7CiAgICB9IGVsc2UgaWYgKG5leHQtPnR5cGUgPT0gdG9rZW46OnR5cGVfb3BhcmVuKSB7CiAgICAgICAgZG91YmxlIHIgPSBkb190ZXJtKCsrbmV4dCwgdmFycyk7CiAgICAgICAgaWYgKG5leHQtPnR5cGUgIT0gdG9rZW46OnR5cGVfY3BhcmVuKSBlcnJvcigiZXhwZWN0ZWQgY2xvc2luZyBwYXJhbSIsICpuZXh0KTsKICAgICAgICArK25leHQ7CiAgICAgICAgcmV0dXJuIHI7CiAgICB9IGVsc2UgZXJyb3IoIkV4cGVjdGVkIHZhbHVlIiwgKm5leHQpOyByZXR1cm4gMC4wOwp9CiAKZG91YmxlIGRvX2ZhY3Rvcih0b2tlbl9pdGVyJiBuZXh0LCBjb25zdCB2YXJpYWJsZV9tYXAmIHZhcnMpIHsKICAgIGRvdWJsZSBsaHMgPSBkb192YWx1ZShuZXh0LCB2YXJzKTsKICAgIHdoaWxlKG5leHQtPnR5cGUgPT0gdG9rZW46OnR5cGVfbXVsIAogICAgICAgICAgICB8fCBuZXh0LT50eXBlID09IHRva2VuOjp0eXBlX2RpdiAKICAgICAgICAgICAgfHwgbmV4dC0+dHlwZSA9PSB0b2tlbjo6dHlwZV9tb2QpIAogICAgewogICAgICAgIHRva2VuOjp0b2tfdHlwZSBvcCA9IG5leHQtPnR5cGU7CiAgICAgICAgZG91YmxlIHJocyA9IGRvX3ZhbHVlKCsrbmV4dCwgdmFycyk7CiAgICAgICAgc3dpdGNoKG9wKSB7CiAgICAgICAgY2FzZSB0b2tlbjo6dHlwZV9tdWw6IAogICAgICAgICAgICBsaHMgKj0gcmhzOyAKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSB0b2tlbjo6dHlwZV9kaXY6IAogICAgICAgICAgICBpZiAocmhzID09IDApIGVycm9yKCJkaXZpc2lvbiBieSB6ZXJvIiwgKm5leHQpOwogICAgICAgICAgICBsaHMgLz0gcmhzOyAKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSB0b2tlbjo6dHlwZV9tb2Q6IAogICAgICAgICAgICBpZiAocmhzID09IDApIGVycm9yKCJtb2R1bG8gYnkgemVybyIsICpuZXh0KTsKICAgICAgICAgICAgbGhzIC89IHJoczsgCiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6IGVycm9yKCJwYXJzZXIgZXJyb3IiLCAqbmV4dCk7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGxoczsKfQogCmRvdWJsZSBkb190ZXJtKHRva2VuX2l0ZXImIG5leHQsIGNvbnN0IHZhcmlhYmxlX21hcCYgdmFycykgewogICAgZG91YmxlIGxocyA9IGRvX2ZhY3RvcihuZXh0LCB2YXJzKTsKICAgIHdoaWxlKG5leHQtPnR5cGUgPT0gdG9rZW46OnR5cGVfYWRkIAogICAgICAgICAgICB8fCBuZXh0LT50eXBlID09IHRva2VuOjp0eXBlX3N1YikgCiAgICB7CiAgICAgICAgdG9rZW46OnRva190eXBlIG9wID0gbmV4dC0+dHlwZTsKICAgICAgICBkb3VibGUgcmhzID0gZG9fZmFjdG9yKCsrbmV4dCwgdmFycyk7CiAgICAgICAgc3dpdGNoKG9wKSB7CiAgICAgICAgY2FzZSB0b2tlbjo6dHlwZV9hZGQ6IGxocyArPSByaHM7IGJyZWFrOwogICAgICAgIGNhc2UgdG9rZW46OnR5cGVfc3ViOiBsaHMgLT0gcmhzOyBicmVhazsKICAgICAgICBkZWZhdWx0OiBlcnJvcigicGFyc2VyIGVycm9yIiwgKm5leHQpOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBsaHM7Cn0KIAppbnQgbWFpbigpIHsKICAgIHRyeSB7CiAgICAgICAgdmFyaWFibGVfbWFwIHZhcnM7CiAgICAgICAgdmFyc1siYXIiXSA9IDMuMTQxNTk7CiAgICAgICAgdmFyc1sidmFyIl0gPSAtLjU7CiAgICAgICAgc3RkOjp2ZWN0b3I8dG9rZW4+IHRva2VuczsKICAgICAgICAvL3N0ZDo6Y291dCA8PCAiZ29hbDpcbjg3NjM1KzIzNzU0KmFyK2FyKnZhciowLjg5NSsoYXItdmFyKSthciphcit2YXIqdmFyICAgICA9MTYyMjcyLjY4NDE3NlxuIjsKICAgICAgICAvL3N0ZDo6Y291dCA8PCAiaW5wdXQ6XG4iOwogICAgICAgIHN0ZDo6Y2luID4+IHRva2VuczsKICAgICAgICBpZiAodG9rZW5zLmVtcHR5KCkpCiAgICAgICAgICAgIHRocm93IHN0ZDo6cnVudGltZV9lcnJvcigiZmFpbGVkIHRvIHJlYWQgYW55IHRva2VucyEiKTsKICAgICAgICB0b2tlbl9pdGVyIGl0ID0gdG9rZW5zLmJlZ2luKCk7CiAgICAgICAgZG91YmxlIHIgPSBkb190ZXJtKGl0LCB2YXJzKTsKICAgICAgICBpZiAoaXQgIT0gdG9rZW5zLmVuZCgpLTEpCiAgICAgICAgICAgIGVycm9yKCJwYXJzZXIgZXJyb3IiLCAqaXQpOwogICAgICAgIHN0ZDo6Y291dCA8PCBzdGQ6OnNldHByZWNpc2lvbigxNCkgPDwgcjsKICAgIH0gY2F0Y2goY29uc3Qgc3RkOjpleGNlcHRpb24mIHJocykgewogICAgICAgIHN0ZDo6Y2VyciA8PCByaHMud2hhdCgpOwogICAgfSAKICAgIHJldHVybiAwOwp9