- #include <istream>
- #include <cassert>
- #include <cmath>
- #include "complex.h"
- // declarations
- // ------------
- // PRE: is = expression...
- // POST: expression is extracted from is, and
- // its value is returned
- Complex expression(std::istream& is);
- // PRE: is = term...
- // POST: term is extracted from is, and
- // its value is returned
- Complex& term(std::istream& is);
- // PRE: is = factor...
- // POST: factor is extracted from is, and
- // its value is returned
- Complex& factor(std::istream& is);
- // definitions
- // -----------
- // POST: the first next character at the stream is returned (but not consumed)
- char peek(std::istream& input) {
- if (input.eof()) {
- return 0; // end of stream
- } else {
- return input.peek(); // next character in input
- }
- }
- // 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
- }
- }
- // POST: if next character in is is ch, consume c and return
- // true, otherwise return false
- bool consume(std::istream& is, char c) {
- if (lookahead(is) == c) {
- is >> c;
- return true;
- } else {
- return false;
- }
- }
- // POST: returns a complex number consumed from the stream
- Complex number(std::istream& is) {
- Complex num;
- is >> num;
- return num;
- }
- // expression = term { "+" term | "-" term }
- Complex expression(std::istream& is) {
- Complex value = term(is); // term
- while (true) {
- if (consume(is, '+')) {
- value = value + term(is); // "+" term
- } else if (consume(is, '-')) {
- value = value - term(is); // "-" term
- } else {
- return value;
- }
- }
- }
- // term = factor { "*" factor | "/" factor }
- Complex& term (std::istream& is) {
- Complex value = factor(is); // factor
- while (true) {
- if (consume(is, '*')) {
- value = value * factor(is); // "*" factor
- } else if (consume(is, '/')) {
- value = value / factor(is); // "/" factor
- } else {
- return value;
- }
- }
- }
- // factor = unsigned_double | "(" expression ")" | -factor
- Complex& factor (std::istream& is) {
- Complex value;
- if (consume(is, '(')) {
- value = expression(is); // "(" expression
- consume(is, ')'); // ")"
- } else if (consume(is, '-')) {
- value = -factor(is); // - factor
- } else {
- value = number(is); // unsigned_double
- }
- return value;
- }
- // POST: returns if from stream input a
- // valid evaluation could be consumed
- // evaluation = expression "=".
- Complex evaluation(std::istream& input) {
- Complex value = expression(input);
- assert(consume(input,'='));
- return value;
- }
- int main() {
- std::cout << "input expressions followed by '=' each\n";
- std::cout << evaluation(std::cin) << "\n";
- return 0;
- }