#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;
}