Problem p00684 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <cassert>
#include <cctype>
#include <cmath>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <memory.h>
#include <memory>
#include <numeric>
#include <queue>
#include <sstream>
#include <string>
#include <vector>

using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef pair<int, P> PP;
typedef pair<P, P> P2;
const int INF = 1 << 30;
const double EPS = 1E-9;

string s;
size_t cur;

P expression();

int rnum() {
  int res = 0;
  while (cur < s.size() && isdigit(s[cur])) {
    res = res * 10 + s[cur++] - '0';
    if (res > 10000) {
      while (cur < s.size())
        cur++;
      return INF;
    }
  }
  return res;
}

P number() {
  if (s[cur] == 'i') {
    cur++;
    return P(0, 1);
  } else {
    P p(0, 0);
    p.first = rnum();
    if (p.first == INF)
      return P(INF, INF);
    return p;
  }
}

P term() {
  P a;
  P b;
  if (s[cur] == '(') {
    cur++;
    a = expression();
    if (cur >= s.size())
      return a;
    assert(s[cur] == ')');
    cur++;
  } else {
    a = number();
  }
  if (abs(a.first) > 10000 || abs(a.second) > 10000) {
    while (cur < s.size())
      cur++;
    return P(INF, INF);
  }
  while (cur < s.size() && (s[cur] == '*')) {
    cur++;
    assert(cur < s.size());
    if (s[cur] == '(') {
      cur++;
      assert(cur < s.size());
      b = expression();
      if (cur >= s.size())
        return b;
      assert(s[cur] == ')');
      cur++;
    } else {
      b = number();
    }
    if (abs(b.first) > 10000 || abs(b.second) > 10000) {
      while (cur < s.size())
        cur++;
      return P(INF, INF);
    }
    int a1 = a.first;
    int a2 = a.second;
    a.first = a1 * b.first - a2 * b.second;
    a.second = a1 * b.second + a2 * b.first;
    if (abs(a.first) > 10000 || abs(b.second) > 10000) {
      while (cur < s.size())
        cur++;
      return P(INF, INF);
    }
  }
  return a;
}

P expression() {
  P a = term();
  if (abs(a.first) > 10000 || abs(a.second) > 10000) {
    while (cur < s.size())
      cur++;
    return P(INF, INF);
  }
  P b;
  while (cur < s.size() && (s[cur] == '+' || s[cur] == '-')) {
    char op = s[cur++];
    assert(cur < s.size());
    b = term();
    if (abs(b.first) > 10000 || abs(b.second) > 10000) {
      while (cur < s.size())
        cur++;
      return P(INF, INF);
    }
    if (op == '+') {
      a.first += b.first;
      a.second += b.second;
    } else {
      a.first -= b.first;
      a.second -= b.second;
    }
    if (abs(a.first) > 10000 || abs(a.second) > 10000) {
      while (cur < s.size())
        cur++;
      return P(INF, INF);
    }
  }
  return a;
}

int main() {
  while (cin >> s) {
    if (s.empty())
      break;
    cur = 0;
    P p = expression();
    if (abs(p.first) > 10000 || abs(p.second) > 10000) {
      cout << "overflow" << endl;
    } else {
      if (p.first != 0) {
        cout << p.first;
        if (p.second != 0) {
          if (p.second > 0)
            cout << "+";
          cout << p.second << "i";
        }
      } else {
        if (p.second == 0) {
          cout << 0;
        } else {
          cout << p.second << "i";
        }
      }
      cout << endl;
    }
  }
  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cctype>
#include <cmath>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <memory.h>
#include <memory>
#include <numeric>
#include <queue>
#include <sstream>
#include <string>
#include <vector>

using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef pair<int, P> PP;
typedef pair<P, P> P2;
const int INF = 1 << 30;
const double EPS = 1E-9;

string s;
size_t cur;

P expression();

int rnum() {
  int res = 0;
  while (cur < s.size() && isdigit(s[cur])) {
    res = res * 10 + s[cur++] - '0';
    if (res > 10000) {
      while (cur < s.size() && isdigit(s[cur]))
        cur++;
      return INF;
    }
  }
  return res;
}

P number() {
  if (s[cur] == 'i') {
    cur++;
    return P(0, 1);
  } else {
    P p(0, 0);
    p.first = rnum();
    if (p.first == INF)
      return P(INF, INF);
    return p;
  }
}

P term() {
  P a;
  P b;
  if (s[cur] == '(') {
    cur++;
    a = expression();

    assert(s[cur] == ')');
    cur++;
  } else {
    a = number();
  }
  if (abs(a.first) > 10000 || abs(a.second) > 10000)
    return P(INF, INF);
  while (cur < s.size() && (s[cur] == '*')) {
    cur++;
    assert(cur < s.size());
    if (s[cur] == '(') {
      cur++;
      assert(cur < s.size());
      b = expression();
      assert(s[cur] == ')');
      cur++;
    } else {
      b = number();
    }
    if (abs(b.first) > 10000 || abs(b.second) > 10000)
      return P(INF, INF);
    int a1 = a.first;
    int a2 = a.second;
    a.first = a1 * b.first - a2 * b.second;
    a.second = a1 * b.second + a2 * b.first;
    if (abs(a.first) > 10000 || abs(b.second) > 10000)
      return P(INF, INF);
  }
  return a;
}

P expression() {
  P a = term();
  if (abs(a.first) > 10000 || abs(a.second) > 10000)
    return a;
  P b;
  while (cur < s.size() && (s[cur] == '+' || s[cur] == '-')) {
    char op = s[cur++];
    assert(cur < s.size());
    b = term();
    if (op == '+') {
      a.first += b.first;
      a.second += b.second;
    } else {
      a.first -= b.first;
      a.second -= b.second;
    }
    if (abs(a.first) > 1000 || abs(a.second) > 10000)
      return a;
  }
  return a;
}

int main() {
  while (getline(cin, s)) {
    if (s.empty())
      break;
    cur = 0;
    P p = expression();
    if (abs(p.first) > 10000 || abs(p.second) > 10000) {
      cout << "overflow" << endl;
    } else {
      cout << p.first;
      if (p.second != 0) {
        if (p.second > 0)
          cout << '+' << p.second << "i";
        else
          cout << p.second << "i";
      }
      cout << endl;
    }
  }
  return 0;
}