Last active
December 21, 2015 00:19
-
-
Save chengluyu/6219251 to your computer and use it in GitHub Desktop.
Calculator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <stdexcept> | |
#include <string> | |
#include <sstream> | |
#include <cmath> | |
using namespace std; | |
class parse_error : exception { | |
string msg; | |
public: | |
parse_error(const char * str) : msg(str) { } | |
virtual ~parse_error() throw () { } | |
virtual const char * what() const throw () { | |
return msg.c_str(); | |
} | |
}; | |
void error(const char * info) { | |
throw parse_error(info); | |
} | |
double T(istream & in); | |
double S(istream & in) { | |
double val = T(in); | |
while (in.peek() == '-' || in.peek() == '+') | |
if (in.get() == '+') | |
val += T(in); | |
else | |
val -= T(in); | |
return val; | |
} | |
double V(istream & in) { | |
double val; | |
bool negative = false; | |
while (in.peek() == '-' || in.peek() == '+') | |
negative ^= in.get() == '-'; | |
if (in.peek() == '(') { | |
in.get(); | |
val = S(in); | |
if (in.get() != ')') | |
error("Bracket doesn't match."); | |
} else { | |
if (!isdigit(in.peek())) | |
error("Missing a operand."); | |
in >> val; | |
} | |
return negative ? -val : val; | |
} | |
double U(istream & in) { | |
double val = V(in), index, result; | |
if (in.peek() == '^') { | |
in.get(); | |
index = U(in); | |
result = pow(val, index); | |
} else | |
result = val; | |
return result; | |
} | |
double T(istream & in) { | |
double val = U(in); | |
while (in.peek() == '*' || in.peek() == '/') | |
if (in.get() == '*') | |
val *= U(in); | |
else | |
val /= U(in); | |
return val; | |
} | |
int main(int argc, const char *argv[]) { | |
// istringstream in("1.2+(9.6^2.5---3+9*9)"); | |
istream & in = cin; | |
try { | |
cout << S(in) << endl; | |
} catch (parse_error e) { | |
cerr << e.what() << endl; | |
} | |
return 0; | |
} |
82488059
commented
Aug 15, 2013
这倒不错,spirit十分方便,直接写cfg就行了,不过一直嫌boost配置太麻烦。
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment