// Prog: texpression_calculator_l.cpp // builds an expression tree corresponding to an 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 #include"texpression.cpp" typedef ifmp::texpression value; //typedef double value; // declarations // ------------ // PRE: is = expression... // POST: expression e is extracted from is, and // its value Sigma (0, +, e) is returned value expression (value v, char sign, std::istream& is); value expression (std::istream& is); // PRE: is = term... // POST: term S is extracted from is, and // the value Pi (1, *, t) is returned value term (value v, char sign, std::istream& is); value term (std::istream& is); // PRE: is = factor... // POST: factor f is extracted from is, and // its value is returned value 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. value expression (value v, char sign, std::istream& is){ if (sign == '+') v += term(is); else if (sign == '-') v -= term(is); else v = term(is); char c = lookahead (is); if (c == '+' || c == '-') return expression (v, c, is >> c); return v; } value expression(std::istream & is){ return expression (0.0, 'X', is); } // term = factor | factor "*" term | factor "/" term. value term (value v, char sign, std::istream& is){ if (sign == '*') v *= factor(is); else if (sign == '/') v /= factor(is); else v = factor(is); char c = lookahead (is); if (c == '*' || c == '/') return term (v, c, is >> c); return v; } value term (std::istream& is){ return term (1.0,'X',is); } // factor = "(" expression ")" | "-" factor | unsigned double. value factor (std::istream& is) { value 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; }