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

#include <bits/stdc++.h>
using namespace std;

#define State string::const_iterator
class ParseError {};

int expression(State &begin);
// int term(State &begin);
int number(State &begin);
int factor(State &begin);
int denial(State &begin);
void consume(State &begin, char expected);
int p, q, r;
string input;

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

  while (true) {
    if (*begin == '+') {
      consume(begin, '+');
      int num = factor(begin);
      // cout << num << " + " << ret;
      if (ret == 0 && num == 0) {
        ret = 0;
      } else if (ret == 1 || num == 1) {
        if (ret != 2 && num != 2) {
          ret = 1;
        } else {
          ret = 2;
        }
      } else {
        ret = 2;
      }
      // cout << " = " << ret << endl;
    } else if (*begin == '*') {
      consume(begin, '*');
      int num = factor(begin);
      // cout << num << " * " << ret;
      if (num == 2 && ret == 2) {
        ret = 2;
      } else if (num == 0 || ret == 0) {
        ret = 0;
      } else {
        ret = 1;
      }
      // cout << " = " << ret << endl;
    } else {
      break;
    }
  }

  return ret;
}

int denial(State &begin) {
  if (*begin == '-') {

    consume(begin, '-');

    int ret = factor(begin);

    if (ret == 2) {
      ret = 0;
    } else if (ret == 0) {
      ret = 2;
    }

    return ret;
  }
  return number(begin);
}

// 数字の列をパースして、その数を返す。
int number(State &begin) {

  if (*begin == 'P') {
    consume(begin, 'P');
    return p;
  } else if (*begin == 'Q') {
    consume(begin, 'Q');
    return q;
  } else if (*begin == 'R') {
    consume(begin, 'R');
    return r;
  }

  int ret = 0;

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

  return ret;
}

// 括弧か数をパースして、その評価結果を返す。
int factor(State &begin) {
  if (*begin == '(') {
    consume(begin, '('); // '('を飛ばす。
    int ret = expression(begin);
    consume(begin, ')'); // ')'を飛ばす。
    return ret;
  } else {
    return denial(begin);
  }
}
// beginがexpectedを指していたらbeginを一つ進める。
void consume(State &begin, char expected) {
  if (*begin == expected) {
    begin++;
  } else {
    cerr << "Expected '" << expected << "' but got '" << *begin << "'" << endl;
    cerr << "Rest string is '";
    while (*begin) {
      cerr << *begin++;
    }
    cerr << "'" << endl;
    cerr << input.end() - begin << endl;
    throw ParseError();
  }
}

int main() {

  while (true) {

    cin >> input;

    if (input[0] == '.') {
      break;
    }

    int ans = 0;

    for (int i = 0; i < 3; i++) {
      for (int j = 0; j < 3; j++) {
        for (int k = 0; k < 3; k++) {
          p = i;
          q = j;
          r = k;
          State s = input.begin();
          if (factor(s) == 2) {
            ans++;
          }
        }
      }
    }

    cout << ans << endl;
  }

  return 0;
}


Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

#define State string::const_iterator
class ParseError {};

int expression(State &begin);
// int term(State &begin);
int number(State &begin);
int factor(State &begin);
int denial(State &begin);
void consume(State &begin, char expected);
int p, q, r;
string input;

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

  while (true) {
    if (*begin == '+') {
      consume(begin, '+');
      int num = factor(begin);
      // cout << num << " + " << ret;
      if (ret == 0 && num == 0) {
        ret = 0;
      } else if (ret == 1 || num == 1) {
        if (ret != 2 && num != 2) {
          ret = 1;
        } else {
          ret = 2;
        }
      } else {
        ret = 2;
      }
      // cout << " = " << ret << endl;
    } else if (*begin == '*') {
      consume(begin, '*');
      int num = factor(begin);
      // cout << num << " * " << ret;
      if (num == 2 && ret == 2) {
        ret = 2;
      } else if (num == 0 || ret == 0) {
        ret = 0;
      } else {
        ret = 1;
      }
      // cout << " = " << ret << endl;
    } else {
      break;
    }
  }

  return ret;
}

int denial(State &begin) {
  if (*begin == '-') {

    consume(begin, '-');

    int ret = denial(begin);

    if (ret == 2) {
      ret = 0;
    } else if (ret == 0) {
      ret = 2;
    }

    return ret;
  }
  return number(begin);
}

// 数字の列をパースして、その数を返す。
int number(State &begin) {

  if (*begin == 'P') {
    consume(begin, 'P');
    return p;
  } else if (*begin == 'Q') {
    consume(begin, 'Q');
    return q;
  } else if (*begin == 'R') {
    consume(begin, 'R');
    return r;
  }

  int ret = 0;

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

  return ret;
}

// 括弧か数をパースして、その評価結果を返す。
int factor(State &begin) {
  if (*begin == '(') {
    consume(begin, '('); // '('を飛ばす。
    int ret = expression(begin);
    consume(begin, ')'); // ')'を飛ばす。
    return ret;
  } else {
    return denial(begin);
  }
}
// beginがexpectedを指していたらbeginを一つ進める。
void consume(State &begin, char expected) {
  if (*begin == expected) {
    begin++;
  } else {
    cerr << "Expected '" << expected << "' but got '" << *begin << "'" << endl;
    cerr << "Rest string is '";
    while (*begin) {
      cerr << *begin++;
    }
    cerr << "'" << endl;
    cerr << input.end() - begin << endl;
    throw ParseError();
  }
}

int main() {

  while (true) {

    cin >> input;

    if (input[0] == '.') {
      break;
    }

    int ans = 0;

    for (int i = 0; i < 3; i++) {
      for (int j = 0; j < 3; j++) {
        for (int k = 0; k < 3; k++) {
          p = i;
          q = j;
          r = k;
          State s = input.begin();
          if (factor(s) == 2) {
            ans++;
          }
        }
      }
    }

    cout << ans << endl;
  }

  return 0;
}