Problem p00259 (C++)

Buggy submission (status: Runtime Error):
#define _CRT_SECURE_NO_WARNINGS
// #define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int, int> pii;
#define all(c) (c).begin(), (c).end()
#define loop(i, a, b) for (ll i = a; i < ll(b); i++)
#define rep(i, b) loop(i, 0, b)
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define mt make_tuple
template <class T> ostream &operator<<(ostream &os, vector<T> const &);
template <int n, class... T>
typename enable_if<(n >= sizeof...(T))>::type _ot(ostream &,
                                                  tuple<T...> const &) {}
template <int n, class... T>
typename enable_if<(n < sizeof...(T))>::type _ot(ostream &os,
                                                 tuple<T...> const &t) {
  os << (n == 0 ? "" : " ") << get<n>(t);
  _ot<n + 1>(os, t);
}
template <class... T> ostream &operator<<(ostream &os, tuple<T...> const &t) {
  _ot<0>(os, t);
  return os;
}
template <class T, class U>
ostream &operator<<(ostream &os, pair<T, U> const &p) {
  return os << "(" << p.first << ", " << p.second << ") ";
}
template <class T> ostream &operator<<(ostream &os, vector<T> const &v) {
  rep(i, v.size()) os << v[i] << (i + 1 == (int)v.size() ? "" : " ");
  return os;
}
#ifdef DEBUG
#define dump(...)                                                              \
  (cerr << #__VA_ARGS__ << " = " << mt(__VA_ARGS__) << " [" << __LINE__ << "]" \
        << endl)
#else
#define dump(...)
#endif

// Verify : http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1102

class zerodive {};

#undef MCR
#define MCR Mint const &
int M;
struct Mint {
  int x;
  explicit Mint() : x(0) {}
  explicit Mint(int y) {
    if ((x = y % M + M) >= M)
      x -= M;
  }
  Mint &operator+=(MCR m) {
    if ((x += m.x) >= M)
      x -= M;
    return *this;
  }
  Mint &operator-=(MCR m) {
    if ((x += M - m.x) >= M)
      x -= M;
    return *this;
  }
  Mint &operator*=(MCR m) {
    x = 1LL * x * m.x % M;
    return *this;
  }
  Mint &operator/=(MCR m) {
    if (m.x % M == 0)
      throw zerodive();
    x = (1LL * x * m.exp(M - 2).x) % M;
    return *this;
  }
  Mint operator+(MCR m) const { return Mint(*this) += m; }
  Mint operator-(MCR m) const { return Mint(*this) -= m; }
  Mint operator*(MCR m) const { return Mint(*this) *= m; }
  Mint operator/(MCR m) const { return Mint(*this) /= m; }
  bool operator<(MCR m) const { return x < m.x; }
  Mint inv() const { return exp(M - 2); }
  Mint exp(long long t) const {
    /* !! default 0^0 = 1 !! */
    // if(x==0) return Mint(0);
    Mint e = *this, res = Mint(1);
    for (; t; e *= e, t >>= 1)
      if (t & 1)
        res *= e;
    return res;
  }
};
ostream &operator<<(ostream &os, Mint m) { return os << m.x; }

char e[1000];

typedef Mint C;

inline bool valid(C) { return true; }

class overflow {};

C expr(char *&p);
C term(char *&p);
C fact(char *&p);
C num(char *&p);

inline bool ispm(char c) { return c == '+' || c == '-'; }
inline bool ispd(char c) { return c == '*' || c == '/'; }

C num(char *&p) {
  C res(0);
  if (isdigit(*p) || *p == 'i') {
    ;
  } else {
    throw "num begin";
  }
  if (isdigit(*p)) {
    while (isdigit(*p)) {
      res *= C(10);
      res += C(*p - '0');
      if (!valid(res))
        throw overflow();
      p++;
    }
  } else {
    // res = C(0,1);
    p++;
  }

  if (*p == '\0' || *p == ')' || ispm(*p) || ispd(*p)) {
    ;
  } else {
    throw "num end";
  }

  if (!valid(res))
    throw overflow();
  return res;
}

C fact(char *&p) {
  C res(0);
  if (*p == '(' || isdigit(*p) || *p == 'i') {
    ;
  } else {
    throw "fact begin";
  }

  if (*p == '(') {
    p++;
    res += expr(p);
    p++;
  } else if (isdigit(*p) || *p == 'i') {
    res += num(p);
  }
  if (*p == '\0' || *p == ')' || ispm(*p) || ispd(*p)) {
    ;
  } else {
    cout << p - e << endl;
    throw "fact end";
  }

  if (!valid(res))
    throw overflow();
  return res;
}

C term(char *&p) {
  C res;
  if (*p == '(' || isdigit(*p) || *p == 'i') {
    res = fact(p);
  } else {
    throw "term begin";
  }
  while (1) {
    if (*p == '*') {
      p++;
      res *= fact(p);
    } else if (*p == '/') {
      p++;
      res /= fact(p);
    } else if (*p == '\0' || *p == ')' || *p == '+' || *p == '-') {
      break;
    } else {
      throw "term end";
    }
    if (!valid(res))
      throw overflow();
  }

  if (!valid(res))
    throw overflow();
  return res;
}

C expr(char *&p) {
  C res;
  if (*p == '(' || isdigit(*p) || *p == 'i') {
    res = term(p);
  } else {
    throw "exp begin";
  }

  while (1) {
    if (*p == '+') {
      p++;
      res += term(p);
    } else if (*p == '-') {
      p++;
      res -= term(p);
    } else if (*p == '\0' || *p == ')') {
      break;
    } else {
      throw "exp end";
    }
    if (!valid(res))
      throw overflow();
  }

  return res;
}

int main() {
  while (cin >> M && M) {
    string s;
    getline(cin, s);
    int ln = 0;
    rep(i, s.size()) {
      if (s[i] == ' ' || s[i] == ':')
        continue;
      e[ln++] = s[i];
    }
    e[ln] = 0;
    try {
      char *p = e;
      auto ans = expr(p);
      printf("%s = %d (mod %d)\n", e, ans.x, M);
    } catch (const zerodive exp) {
      puts("NG");
    } catch (const char *) {
      puts("NG");
    }
  }
}

Fixed submission:
#define _CRT_SECURE_NO_WARNINGS
// #define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int, int> pii;
#define all(c) (c).begin(), (c).end()
#define loop(i, a, b) for (ll i = a; i < ll(b); i++)
#define rep(i, b) loop(i, 0, b)
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define mt make_tuple
template <class T> ostream &operator<<(ostream &os, vector<T> const &);
template <int n, class... T>
typename enable_if<(n >= sizeof...(T))>::type _ot(ostream &,
                                                  tuple<T...> const &) {}
template <int n, class... T>
typename enable_if<(n < sizeof...(T))>::type _ot(ostream &os,
                                                 tuple<T...> const &t) {
  os << (n == 0 ? "" : " ") << get<n>(t);
  _ot<n + 1>(os, t);
}
template <class... T> ostream &operator<<(ostream &os, tuple<T...> const &t) {
  _ot<0>(os, t);
  return os;
}
template <class T, class U>
ostream &operator<<(ostream &os, pair<T, U> const &p) {
  return os << "(" << p.first << ", " << p.second << ") ";
}
template <class T> ostream &operator<<(ostream &os, vector<T> const &v) {
  rep(i, v.size()) os << v[i] << (i + 1 == (int)v.size() ? "" : " ");
  return os;
}
#ifdef DEBUG
#define dump(...)                                                              \
  (cerr << #__VA_ARGS__ << " = " << mt(__VA_ARGS__) << " [" << __LINE__ << "]" \
        << endl)
#else
#define dump(...)
#endif

// Verify : http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1102

class zerodive {};

#undef MCR
#define MCR Mint const &
int M;
struct Mint {
  int x;
  explicit Mint() : x(0) {}
  explicit Mint(int y) {
    if ((x = y % M + M) >= M)
      x -= M;
  }
  Mint &operator+=(MCR m) {
    if ((x += m.x) >= M)
      x -= M;
    return *this;
  }
  Mint &operator-=(MCR m) {
    if ((x += M - m.x) >= M)
      x -= M;
    return *this;
  }
  Mint &operator*=(MCR m) {
    x = 1LL * x * m.x % M;
    return *this;
  }
  Mint &operator/=(MCR m) {
    if (m.x % M == 0)
      throw zerodive();
    x = (1LL * x * m.exp(M - 2).x) % M;
    return *this;
  }
  Mint operator+(MCR m) const { return Mint(*this) += m; }
  Mint operator-(MCR m) const { return Mint(*this) -= m; }
  Mint operator*(MCR m) const { return Mint(*this) *= m; }
  Mint operator/(MCR m) const { return Mint(*this) /= m; }
  bool operator<(MCR m) const { return x < m.x; }
  Mint inv() const { return exp(M - 2); }
  Mint exp(long long t) const {
    /* !! default 0^0 = 1 !! */
    // if(x==0) return Mint(0);
    Mint e = *this, res = Mint(1);
    for (; t; e *= e, t >>= 1)
      if (t & 1)
        res *= e;
    return res;
  }
};
ostream &operator<<(ostream &os, Mint m) { return os << m.x; }

char e[1000000];

typedef Mint C;

inline bool valid(C) { return true; }

class overflow {};

C expr(char *&p);
C term(char *&p);
C fact(char *&p);
C num(char *&p);

inline bool ispm(char c) { return c == '+' || c == '-'; }
inline bool ispd(char c) { return c == '*' || c == '/'; }

C num(char *&p) {
  C res(0);
  if (isdigit(*p) || *p == 'i') {
    ;
  } else {
    throw "num begin";
  }
  if (isdigit(*p)) {
    while (isdigit(*p)) {
      res *= C(10);
      res += C(*p - '0');
      if (!valid(res))
        throw overflow();
      p++;
    }
  } else {
    // res = C(0,1);
    p++;
  }

  if (*p == '\0' || *p == ')' || ispm(*p) || ispd(*p)) {
    ;
  } else {
    throw "num end";
  }

  if (!valid(res))
    throw overflow();
  return res;
}

C fact(char *&p) {
  C res(0);
  if (*p == '(' || isdigit(*p) || *p == 'i') {
    ;
  } else {
    throw "fact begin";
  }

  if (*p == '(') {
    p++;
    res += expr(p);
    p++;
  } else if (isdigit(*p) || *p == 'i') {
    res += num(p);
  }
  if (*p == '\0' || *p == ')' || ispm(*p) || ispd(*p)) {
    ;
  } else {
    cout << p - e << endl;
    throw "fact end";
  }

  if (!valid(res))
    throw overflow();
  return res;
}

C term(char *&p) {
  C res;
  if (*p == '(' || isdigit(*p) || *p == 'i') {
    res = fact(p);
  } else {
    throw "term begin";
  }
  while (1) {
    if (*p == '*') {
      p++;
      res *= fact(p);
    } else if (*p == '/') {
      p++;
      res /= fact(p);
    } else if (*p == '\0' || *p == ')' || *p == '+' || *p == '-') {
      break;
    } else {
      throw "term end";
    }
    if (!valid(res))
      throw overflow();
  }

  if (!valid(res))
    throw overflow();
  return res;
}

C expr(char *&p) {
  C res;
  if (*p == '(' || isdigit(*p) || *p == 'i') {
    res = term(p);
  } else {
    throw "exp begin";
  }

  while (1) {
    if (*p == '+') {
      p++;
      res += term(p);
    } else if (*p == '-') {
      p++;
      res -= term(p);
    } else if (*p == '\0' || *p == ')') {
      break;
    } else {
      throw "exp end";
    }
    if (!valid(res))
      throw overflow();
  }

  return res;
}

int main() {
  while (cin >> M && M) {
    string s;
    getline(cin, s);
    int ln = 0;
    rep(i, s.size()) {
      if (s[i] == ' ' || s[i] == ':')
        continue;
      e[ln++] = s[i];
    }
    e[ln] = 0;
    try {
      char *p = e;
      auto ans = expr(p);
      printf("%s = %d (mod %d)\n", e, ans.x, M);
    } catch (const zerodive exp) {
      puts("NG");
    } catch (const char *) {
      puts("NG");
    }
  }
}