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

#include <cassert>
#include <cctype>
#include <iostream>
#include <string>
using namespace std;

#define REP(i, b, n) for (int i = b; i < n; i++)
#define rep(i, n) REP(i, 0, n)

string S = "3*(12+3)";
size_t cur = 0;

int expression();

int digit() {
  assert(isdigit(S[cur]));
  int n = S[cur] - '0';
  cur++;
  return n;
}

int number() {
  int n = digit();
  while (cur < S.size() && isdigit(S[cur]))
    n = n * 10 + digit();
  return n;
}

int factor() {
  if (S[cur] != '(')
    return number();
  cur += 1;
  int n = expression();
  assert(S[cur] == ')');
  cur++;
  return n;
}

int term() {
  int a = factor();
  while (cur < S.size() && (S[cur] == '*' || S[cur] == '/')) {
    char op = S[cur++];
    int b = factor();
    if (op == '*')
      a *= b;
    else
      a /= b;
  }
  return a;
}

int expression() {
  int a = term();
  while (cur < S.size() && (S[cur] == '+' || S[cur] == '-')) {
    char op = S[cur++];
    int b = term();
    if (op == '+')
      a += b;
    else
      a -= b;
  }
  return a;
}

int parse() {
  cur = 0;
  return expression();
}

int main(int argc, char const *argv[]) {
  int n;
  cin >> n;
  rep(i, n) {
    cin >> S;
    S.erase(S.size() - 1);
    // cout<<S<<endl;
    cout << parse() << endl;
  }
  return 0;
}

Error: 0

Fixed submission:

#include <cstdlib>
#include <iostream>
#include <sstream>
#include <string>
using namespace std;

#define REP(i, b, n) for (int i = b; i < n; i++)
#define rep(i, n) REP(i, 0, n)

bool is_digit(char c) { return '0' <= c && c <= '9'; }
string i2s(int i) {
  stringstream ss;
  ss << i;
  return ss.str();
}

string parse(int i, string s) {
  // cout<<s<<endl;
  bool flag = true;

  // brace
  if (s.find('(') != -1) {
    // æª©ç`FbNµÄA')'Éoï¤êÆ
    // »¤ÅÈ¢êÉª¯é
    bool mode = true;
    REP(j, s.find('(') + 1, s.size()) {
      if (s[j] == ')')
        break;
      if (s[j] == '(') {
        mode = false;
        break;
      }
    }
    // ÊÌÊuðæ¾·é
    int lbr = s.find('('), rbr;
    if (mode) {
      rbr = s.find(')');
    } else {
      for (int j = s.size() - 1; j >= 0; j--)
        if (s[j] == ')') {
          rbr = j;
          break;
        }
    }
    // ÊàÌvZðæÉs¤½ßÉssð¾é
    string inner = parse(0, s.substr(lbr + 1, rbr - lbr - 1));
    // ÊàðÁ·é
    s.erase(lbr, rbr - lbr + 1);
    s.insert(lbr, inner);
    // cout<<"brace:"<<s<<endl;
    return parse(0, s);
  }

  rep(i, s.size()) if (s[i] == '*' || s[i] == '/') {
    int lhs, rhs, res;
    int li = i - 1, ri = i + 1;
    if (ri + 1 < s.size() && s[ri] == '-')
      ri++;

    while (is_digit(s[li]) && li >= 0) {
      if (s[li] == '-')
        break;
      li--;
    }
    while (is_digit(s[ri]) && ri < s.size())
      ri++;
    lhs = atoi(s.substr(li + 1, i - 1 - li).c_str());
    rhs = atoi(s.substr(i + 1, ri - 1 - i).c_str());
    // cout<<s.substr(li+1, i-1-li)<<"|"<<s.substr(i+1, ri-1-i)<<endl;

    if (lhs == 0 || rhs == 0) {
      res = 0;
    } else {
      if (s[i] == '*') {
        res = lhs * rhs;
      } else {
        res = lhs / rhs;
      }
    }

    s.erase(li + 1, ri - li - 1);
    s.insert(li + 1, i2s(res));
    // cout<<"tmp:"<<s<<endl;
    return parse(0, s);
  }

  rep(i, s.size()) if (s[i] == '+' || s[i] == '-') {
    if (s[i] == '-' && i == 0)
      continue;
    int lhs, rhs, res;
    int li = i - 1, ri = i + 1;
    if (ri + 1 < s.size() && s[ri] == '-')
      ri++;

    while (is_digit(s[li]) || s[li] == '-' && li >= 0)
      li--;
    while (is_digit(s[ri]) && ri < s.size())
      ri++;
    lhs = atoi(s.substr(li + 1, i - 1 - li).c_str());
    rhs = atoi(s.substr(i + 1, ri - 1 - i).c_str());
    // cout<<s.substr(li+1, i-1-li)<<"|"<<s.substr(i+1, ri-1-i)<<endl;
    if (s[i] == '+') {
      res = lhs + rhs;
    } else {
      res = lhs - rhs;
    }
    s.erase(li + 1, ri - li - 1);
    s.insert(li + 1, i2s(res));
    // cout<<"tmp:"<<s<<endl;
    return parse(0, s);
  }

  return s;
}

void solve() {
  string s;
  cin >> s;
  s = s.substr(0, s.size() - 1);
  cout << parse(0, s) << endl;
  // cout<<"+++++"<<endl;
}

int main(int argc, char const *argv[]) {
  int n;
  cin >> n;
  rep(i, n) solve();
  return 0;
}