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

/*
  参考元：構文解析 Howto
  (https://gist.github.com/draftcode/1357281)

  構文解析
  <四則演算の式> ::= <乗算除算の式> (+ or -) <乗算除算の式> (+ or -) ...
  <乗算除算の式> ::= <括弧か数> (* or / ) <括弧か数> (* or / ) ...
  <括弧か数> ::= '(' <四則演算の式> ')' or <数>
  <数> ::= ...
*/

#include <cctype>
#include <iostream>
#include <string>

using namespace std;

typedef string::const_iterator State;
class ParseError {};

int number(State &begin);
int factor(State &begin);
int term(State &begin);
int expression(State &begin);

// 数字の列をパースして，その数を返す．
int number(State &begin) {
  int ret = 0;

  while (isdigit(*begin)) {
    ret *= 10;
    ret += *begin - '0';
    begin++;
  }
  return ret;
}

// 括弧か数をパースして，その評価結果を返す．
int factor(State &begin) {
  if (*begin == '(') {
    begin++; // '('を飛ばす
    int ret = expression(begin);
    begin++; // ')'を飛ばす
    return ret;
  } else
    return number(begin);
}

// 乗算除算の式をパースして，その評価結果を返す．
int term(State &begin) {
  int ret = factor(begin);

  while (true) {
    if (*begin == '*') {
      begin++;
      ret *= factor(begin);
    } else if (*begin == '/') {
      begin++;
      ret /= factor(begin);
    } else
      break;
  }

  return ret;
}

// 四則演算の式をパースして，その評価結果を返す．
int expression(State &begin) {
  int ret = term(begin);

  while (true) {
    if (*begin == '+') {
      begin++;
      ret += term(begin);
    } else if (*begin == '-') {
      begin++;
      ret -= term(begin);
    } else
      break;
  }

  return ret;
}

int main() {
  int N;

  cin >> N;
  cin.ignore();
  for (int i = 0; i < N; i++) {
    string s;
    getline(cin, s);

    State begin = s.begin();
    int ans = expression(begin);

    cout << ans << endl;
  }

  return 0;
}

Error: 0
4-2*3=
4.2.3.*-
4*(8+4+3)=
4.8.4.3.++*


Fixed submission:

#include <iostream>
#include <stack>

using namespace std;

int pri(char ch) {
  if (ch == '*' || ch == '/')
    return 2;
  if (ch == '+' || ch == '-')
    return 1;
  else
    return 0;
}

int main() {
  int n;

  cin >> n;

  while (n--) {
    string exp, cha;
    stack<char> pol;
    stack<int> cal;

    cin >> exp;
    for (int i = 0; i < exp.size() - 1; i++) {
      if ('0' <= exp[i] && exp[i] <= '9') {
        while (true) {
          cha.push_back(exp[i]);
          if ('0' > exp[i + 1] || exp[i + 1] > '9') {
            cha.push_back('.');
            break;
          } else
            i++;
        }
      } else if (exp[i] == '(')
        pol.push(exp[i]);
      else if (exp[i] == ')') {
        while (true) {
          if (pol.top() == '(') {
            pol.pop();
            break;
          }
          cha.push_back(pol.top());
          pol.pop();
        }
      } else {
        while (!pol.empty()) {
          if (pri(exp[i]) < pri(pol.top())) {
            cha.push_back(pol.top());
            pol.pop();
          } else
            break;
        }
        pol.push(exp[i]);
      }
    }

    while (!pol.empty()) {
      cha.push_back(pol.top());
      pol.pop();
    }

    cerr << exp << endl;
    cerr << cha << endl;
    for (int i = 0; i < cha.size(); i++) {
      if ('0' <= cha[i] && cha[i] <= '9') {
        int tmp = cha[i] - '0';

        while (true) {
          i++;
          if (cha[i] == '.')
            break;
          tmp *= 10;
          tmp += cha[i] - '0';
        }
        cal.push(tmp);
      } else {
        int a, b;

        b = cal.top();
        cal.pop();
        a = cal.top();
        cal.pop();

        if (cha[i] == '*')
          cal.push(a * b);
        else if (cha[i] == '/')
          cal.push(a / b);
        else if (cha[i] == '+')
          cal.push(a + b);
        else if (cha[i] == '-')
          cal.push(a - b);
      }
    }
    cout << cal.top() << endl;
  }

  return 0;
}