Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<iostream>
- #include<cctype>
- #include<string>
- #include<regex>
- #include<vector>
- #include<map>
- #include<stack>
- using namespace std;
- map<char, int> var = {
- { 'a', 0 },{ 'b', 0 },{ 'c', 0 },{ 'd', 0 },{ 'e', 0 },{ 'f', 0 },{ 'g', 0 },{ 'h', 0 },{ 'i', 0 },{ 'j', 0 },{ 'k', 0 },{ 'l', 0 },
- { 'm', 0 },{ 'n', 0 },{ 'o', 0 },{ 'p', 0 },{ 'q', 0 },{ 'r', 0 },{ 's', 0 },{ 't', 0 },{ 'u', 0 },{ 'v', 0 },{ 'w', 0 },{ 'x', 0 },
- { 'y', 0 },{ 'z', 0 }
- };
- bool isOperand(char c) { return (isdigit(c) || isalpha(c)); }
- bool isOperator(char c) { return (c == '+' || c == '-' || c == '*' || c == '/' || c == '%'); }
- int weight(char c) {
- switch (c) {
- case '+':
- case '-':
- return 1;
- case '*':
- case '/':
- case '%':
- return 2;
- }
- throw "Invalid operator found.";
- }
- int calc(int x, int y, char op) {
- switch (op) {
- case '+':
- return x + y;
- case '-':
- return x - y;
- case '*':
- return x*y;
- case '/':
- if (y == 0) throw "An attempt was made to divide by 0.";
- return x / y;
- case '%':
- if (y == 0) throw "An attempt was made to mod by 0.";
- return x%y;
- }
- throw "Invalid operator discovered.";
- }
- vector<string> toPostfix(string expr) {
- vector<string> postfix;
- stack<char> opstack;
- for (int i = 0; i < expr.length(); i++) {
- if (isOperator(expr[i])) { // we found an operator. Check the weights and add to the stack
- while (!opstack.empty() && opstack.top() != '(' && weight(opstack.top()) > weight(expr[i])) {
- string t(1, opstack.top());
- postfix.push_back(t);
- opstack.pop();
- }
- opstack.push(expr[i]);
- }
- // we found a variable. Add it to the expression.
- else if (isalpha(expr[i])) {
- string t(1, expr[i]);
- postfix.push_back(t);
- }
- else if (isdigit(expr[i])) {
- string t = "";
- while (isdigit(expr[i])) {
- t += expr[i];
- i++;
- }
- postfix.push_back(t);
- i--; // so we don't lose the next character
- }
- else if (expr[i] == '(') // opening parenth. Push to stack
- opstack.push('(');
- else if (expr[i] == ')') { // closing parenth. Add the contents to the expression
- while (!opstack.empty() && opstack.top() != '(') {
- string t(1, opstack.top());
- postfix.push_back(t);
- opstack.pop();
- }
- opstack.pop(); // get rid of the opening parenthesis but don't add it the expression
- }
- else if (expr[i] != ' ') throw "Invalid character found.";
- }
- // now empty the stack
- while (!opstack.empty()) {
- string t(1, opstack.top());
- postfix.push_back(t);
- opstack.pop();
- }
- return postfix;
- }
- int evaluate(vector<string> postfix) {
- stack<int> s;
- for (string i : postfix) { // iterate the postfix expression
- if (isdigit(i[0]))
- s.push(atoi(i.c_str()));
- else if (isalpha(i[0])) // replace variables with their values
- s.push(var[tolower(i[0])]);
- else if (isOperator(i[0])) {
- if (s.size() < 2) throw "An operator requires two arguments.";
- int t = s.top();
- s.pop();
- int val = calc(s.top(), t, i[0]);
- s.pop();
- s.push(val);
- }
- }
- if (s.size() == 1) return s.top();
- cout << "Current stack: " << endl;
- while (!s.empty()) {
- cout << s.top() << endl;
- s.pop();
- }
- throw "Syntax error.";
- }
- int main() {
- cout << "Welcome. Please input an expression, assign a new variable, or type 'exit' to stop." << endl;
- while (true) {
- regex r("^[A-Za-z]\\s=\\s[0-9]+$");
- smatch m;
- cout << "> ";
- string in;
- getline(cin, in);
- // the user wants to quit
- if (in == "exit")
- return 0;
- // the user wants to assign a variable
- else if (regex_search(in, m, r)) {
- char var_ref = tolower(in[0]);
- int num = atoi(in.substr(4).c_str());
- var[var_ref] = num;
- cout << "\t" << num << endl;
- }
- else {
- try {
- cout << "\t" << evaluate(toPostfix(in)) << endl;
- }
- catch (const char* e) {
- cout << "\t" << "Error: " << e << endl;
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement