// Prog: calculator_l.cpp // evaluate arithmetic expressions involving +, -, *, /, (, ) // over double operands, with left-to-right evaluation order // Syntax in BNF: // --------------- // expression = term | term "+" expression | term "-" expression. // term = factor | factor "*" term | factor "/" term. // factor = "(" expression ")" | "-" factor | unsigned double. #include #include #include #include // declarations // ------------ // PRE: is = expression... // POST: expression e is extracted from is, and // its value Sigma (0, +, e) is returned double expression (double v, char sign, std::istream& is); double expression (std::istream& is); // PRE: is = term... // POST: term S is extracted from is, and // the value Pi (1, *, t) is returned double term (double v, char sign, std::istream& is); double term (std::istream& is); // PRE: is = factor... // POST: factor f is extracted from is, and // its value is returned double factor (std::istream& is); // definitions // ----------- // POST: leading whitespace characters are extracted // from is, and the first non-whitespace character // is returned (0 if there is no such character) char lookahead (std::istream& is) { is >> std::ws; // skip whitespaces if (is.eof()) return 0; // end of stream else return is.peek(); // next character in is } // expression = term | term "+" expression | term "-" expression. double expression (double v, char sign, std::istream& is){ if (sign == '+') v += term(is); else if (sign == '-') v -= term(is); char c = lookahead (is); if (c == '+' || c == '-') return expression (v, c, is >> c); return v; } double expression(std::istream & is){ return expression (0.0, '+', is); } // term = factor | factor "*" term | factor "/" term. double term (double v, char sign, std::istream& is){ if (sign == '*') v *= factor(is); else if (sign == '/') v /= factor(is); char c = lookahead (is); if (c == '*' || c == '/') return term (v, c, is >> c); return v; } double term (std::istream & is){ return term (1.0,'*',is); } // factor = "(" expression ")" | "-" factor | unsigned double. double factor (std::istream& is) { double v; char c = lookahead (is); if (c == '(') { v = expression (is >> c); is >> c; assert (c == ')'); } else if (c == '-') { v = -factor(is >> c); } else { double d; is >> d; assert (!is.fail()); v = d; } return v; } int main() { std::stringstream input1 ("-(3-(4-5))*(3+4*5)/6"); // -15.33333 std::stringstream input2 ("3-4-5"); // -6 std::cout << expression (input1) << "\n"; std::cout << expression (input2) << "\n"; return 0; }