1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
|
#include <iostream>
#include <stack>
#include <string>
#include <cctype>
using namespace std;
typedef int ValueType;
int main(void)
{
provideHelpIfNecessary();
while(true){
cout << "Expression? ";
string expr; // holds the supposed expression
getline(cin, expr);
if (expr.length() == 0)
try {
ValueType result = processExpression(expr);
cout << result << endl;
} catch (ZeroDivideException ex) {
cerr << "Attempt to divide by zero!\n";
} catch (IllegalExprException ex) {
cerr << "Illegal infix expression!\n";
}
} // end while
cout << endl;
} // end main
void provideHelpIfNecessary(void)
{
char answer;
cout <<"Do you need help (Y/N)?\n";
cin >> answer;
if (isValidResponse(answer) == false) {
cout << "Invalid response! Try again.";
provideHelpIfNecessary();
}
else if (isValidResponse(answer) == true) {
if (isYesResponse(answer) == true) {
cout << "Enter an infix expression at the prompt.\nThe program will tell you its value.\nTo stop the program, just hit 'return' at the prompt.\n";
}
else return; }
ValueType processExpression(const string& expr)
throw (IllegalExprException, ZeroDivideException)
{
stack<ValueType> ValStack;
stack<char> OpStack;
for (int i = 0; i < expr.length(); i++)
{
if (expr[i] == '0','1','2','3','4','5','6','7','8','9') ValStack.push(expr[i]);
if (expr[i] == '(') OpStack.push(expr[i]);
if (expr[i] == '*', '+', '-', '/') {
if(OpStack.empty()) OpStack.push(expr[i]);
else if (precedence(expr[i]) > precedence(OpStack.top())) OpStack.push(expr[i]);
else
{
if (!OpStack.empty() && precedence(expr[i]) <= precedence(OpStack.top())) execute(ValStack,OpStack);
OpStack.push(expr[i]);
}}
if (expr[i] == ')') {
if (OpStack.top() != '(') execute(ValStack,OpStack);
OpStack.pop();
}}
if (!OpStack.empty()) execute(ValStack,OpStack);
ValueType result = ValStack.top();
return 0;
} // end processExpression
bool isValidResponse(char response)
{
bool valid = false;
if (response == 'Y'||'y'||'T'||'t'||'1'||'N'||'n'||'F'||'f'||'0') return valid = true;
else return valid;
} // end isValidResponse
bool isYesResponse(char response)
{
bool yes = false;
if (response == 'Y'||'y'||'T'||'t'||'1') return yes = true;
else return yes;
} // end isYesResponse
int precedence(char op)
{
if (op == '*' || '/') op = 3;
if (op == '+' || '-') op = 2;
if (op == '(')op = 0;
else op = -1;
return op;
} // end precedence
void execute(stack<ValueType>& valStack, stack<char>& opStack)
throw (IllegalExprException, ZeroDivideException)
{
ValueType result;
ValueType operand2 = valStack.top(); //operandL
valStack.pop();
ValueType operand1 = valStack.top(); //operandR
valStack.pop();
char op = opStack.top();
opStack.pop();
result = doOperation(operand2,op,operand1);
valStack.push(result);
} // end execute
ValueType doOperation(ValueType operandL, char operation, ValueType operandR)
throw (IllegalExprException, ZeroDivideException)
{
ValueType ans;
operandL -= '0';
operandR -= '0';
if (operation == '*') ans = operandL * operandR;
if (operation == '/') ans = operandL / operandR;
if (operation == '+') ans = operandL + operandR;
if (operation == '-') ans = operandL - operandR;
return ans;
} // end doOperation
|