/** * ***************************************************************************** * file name : Postfix_Evaluator.cpp * author : Hung Ngo * description : implement the Postfix_Evaluator interface * ***************************************************************************** */ #include #include #include #include "Lexer.h" #include "error_handling.h" #include "Postfix_Evaluator.h" using namespace std; /** * ----------------------------------------------------------------------------- * lex will provide the input tokens * ----------------------------------------------------------------------------- */ void Postfix_Evaluator::set_expression(Lexer lex) { lexer = lex; } /** * ----------------------------------------------------------------------------- * lex will provide the input tokens * ----------------------------------------------------------------------------- */ double Postfix_Evaluator::eval_op(char op, double a, double b) { switch (op ) { case '+': return a+b; case '-': return a-b; case '*': return a*b; case '/': if (b == 0) throw DBZ_Exception(); return a/b; default: throw runtime_error("Unknown operator"); } } /** * ----------------------------------------------------------------------------- * evaluate the expression provided by lexer * ----------------------------------------------------------------------------- */ double Postfix_Evaluator::eval() { while (!operand_stack.empty()) operand_stack.pop(); // make sure it is empty Token tok; double a, b; // lexer.restart(); while (lexer.has_more_token()) { tok = lexer.next_token(); switch (tok.type) { case INTEGER: { stringstream buffer(tok.value); buffer >> a; operand_stack.push(a); break; } case OPERATOR: if (operand_stack.size() < 2) { throw runtime_error(string("Syntax Error: operator " ) + tok.value + " needs more operand"); } else { b = operand_stack.top(); operand_stack.pop(); a = operand_stack.top(); operand_stack.pop(); operand_stack.push(eval_op(tok.value[0], a, b)); } break; default: throw Syntax_Error_Exception(); } } // end of while loop if (operand_stack.size() != 1) throw Syntax_Error_Exception(); else return operand_stack.top(); }