// testspri.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
//#define BOOST_SPIRIT_NO_REGEX_LIB
//
//#include "D:/boost/boost_1_40_0/boost/regex.h"
//#include "D:/boost/boost_1_40_0/boost/spirit.hpp"
//#include "D:/boost/boost_1_40_0/boost/spirit/actor.hpp"
//using namespace boost::spirit;
#include <string>
#include <iostream>
using namespace std;
//const string input = "This Hello World program using Spirit counts the number of Hello World occurrences in the input";
//
//int main ()
// {
// int count = 0;
// parse (input.c_str(),
// *(str_p("Hello World") [ increment_a(count) ]
// |
// anychar_p)
// );
// cout << count <<endl;
//
// return 0;
// }
//#define BOOST_SPIRIT_NO_REGEX_LIB
//
//#include "D:/boost/boost_1_40_0/boost/regex.h"
//#include "D:/boost/boost_1_40_0/boost/spirit.hpp"
//#include "D:/boost/boost_1_40_0/boost/spirit/actor/assign_actor.hpp"
//
//using namespace std;
//using namespace boost::spirit;
//
//const string input = "Alex 8 9.2 Jim 91 5.6";
//
//typedef struct {
// string name;
// int idcode;
// float rating;
//} Employee;
//
//int main ()
// {
// string name;
// int idcode;
// float rating;
//
// int status = parse (input.c_str(),
// *((+alpha_p) [assign_a(name)] >> ' ' >>
// int_p[assign_a(idcode)] >> ' ' >>
// real_p[assign_a(rating)] >> !blank_p)
// ).full;
// cout << status << endl;
// return 0;
// }
//#define BOOST_SPIRIT_NO_REGEX_LIB
//
//#include "boost/regex.h"
//#include "boost/spirit.hpp"
//#include "boost/spirit/actor/assign_actor.hpp"
//
//using namespace std;
//using namespace boost::spirit;
//
//struct my_enum : public grammar<my_enum>
// {
// template <typename ScannerT>
// struct definition
// {
// definition(my_enum const& self)
// {
// enum_specifier = enum_p >> '{' >> enum_list >> '}';
// enum_p = str_p("enum");
// enum_list = +id_p >> *(',' >> +id_p);
// id_p = range_p('a','z');
// }
//
// rule<ScannerT> enum_specifier, enum_p, enum_list, id_p;
// rule<ScannerT> const& start() const { return enum_specifier; }
// };
// };
//
//string input = "enum { ah, bk }";
//
//int main ()
// {
// my_enum e;
// int status = parse(input.c_str(), e, space_p).hit;
// cout << status << endl;
// return 0;
// }
#include <iostream>
#include <vector>
#include <boost/spirit.hpp>
#include <boost/spirit/phoenix.hpp>
using namespace std;
using namespace boost::spirit;
using namespace phoenix;
//int main()
//{
////为rule准备一个val变量,类型为double
////准确地说:是一个phoenix类(这里的member1),它和其它phoenix类组成lambda表达式,在lambda中可以把它看成是一个double。
//struct calc_closure : boost::spirit::closure<calc_closure, double>
//{
//member1 val;
//};
////定义ContextT策略为calc_closure::context_t
//rule<phrase_scanner_t, calc_closure::context_t> factor, term, exp;
////直接使用phoenix的lambda表达式作为Actor
//factor = real_p[factor.val = arg1] | ('(' >> exp[factor.val = arg1] >> ')');
//term = factor[term.val = arg1] >> *(('*' >> factor[term.val *= arg1]) | ('/' >> factor[term.val /= arg1]));
//exp = term[exp.val = arg1] >> *(('+' >> term[exp.val += arg1]) | ('-' >> term[exp.val -= arg1]));
//const char *szExp = "-1 + (2 * (3 / (4 + 5)))";
//double result;
//parse_info<> r = parse( szExp , exp[assign_a(result)], space_p);
//cout << szExp;
//if(r.full)
//{
////成功,得到结果
//cout << " = " << result << endl;
//}
//else
//{
////失败,显示错误位置
//cout << endl << string(r.stop - szExp, ' ') << '^' << endl;
//}
//return 0;
//}
#include <stack>
#include <string>
#include <cassert>
#include <iostream>
#include <functional>
#include <boost/bind.hpp>
#include <boost/spirit.hpp>
template <typename op>
void CalStack(std::stack<double>& values) {
assert(values.size() >= 2);
double op2 = values.top();
values.pop();
double op1 = values.top();
values.pop();
values.push(op()(op1, op2));
}
void eval(const char* expr) {
using boost::spirit::rule;
using boost::spirit::ch_p;
using boost::spirit::real_p;
using boost::spirit::space_p;
using boost::bind;
using boost::ref;
using std::stack;
typedef double Type;
stack<Type> sValueStack;
// E ::= T ( (+T) | (-T) )*
// T ::= F ( (*F) | (/F) )*
// F ::= ('(' E ')') | 浮点数
rule<> E, F, T;
E = (T >> *(
(ch_p('+') >> T)[bind(&CalStack<std::plus<Type> >, ref(sValueStack))] |
(ch_p('-') >> T)[bind(&CalStack<std::minus<Type> >, ref(sValueStack))]
));
T = (F >> *(
(ch_p('*') >> F)[bind(&CalStack<std::multiplies<Type> >, ref(sValueStack))] |
(ch_p('/') >> F)[bind(&CalStack<std::divides<Type> >, ref(sValueStack))]
));
F = (ch_p('(') >> E >> ch_p(')')) |
(*space_p >> real_p[bind(&stack<Type>::push, ref(sValueStack), _1)] >> *space_p);
if (parse(expr, E).full) {
assert(sValueStack.size() == 1);
std::cout << sValueStack.top() << std::endl;
} else {
std::cout << "计算过程中遇到错误" << std::endl;
}
}
int main() {
std::string input;
while( std::getline(std::cin, input) ) {
eval(input.c_str());
}
}