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

#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <valarray>
#include <vector>
using namespace std;

#define REP(i, n) for (int i = 0; i < (int)n; ++i)
#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define ALL(c) (c).begin(), (c).end()
#define chmax(a, b) (a < b ? (a = b, 1) : 0)
#define chmin(a, b) (a > b ? (a = b, 1) : 0)
#define valid(y, x, h, w) (0 <= y && y < h && 0 <= x && x < w)
typedef unsigned long long ll;
typedef pair<int, int> pii;
const int INF = 1 << 29;
const double PI = acos(-1);
const double EPS = 1e-8;

const ll mod = 1e9 + 7;
typedef pair<ll, ll> pll;

void assign(pll &p, ll a, ll b) {
  p.first = a % mod;
  p.second = b % mod;
}

enum Type { EXPR1, EXPR2, EXPR3, TERM1, TERM2, TERM3, FACT1, FACT2, FACT3 };
struct state {
  Type t;
  pll v;
  state(Type t) : t(t) {}
  state(Type t, pll v) : t(t), v(v) {}
};

int parse(const string &s) {
  int i = 0;
  pll now(
      0,
      0); // テァツ崢エティツソツ妥」ツ?ォテ・ツ?ヲテァツ青?」ツ?療」ツ?淌「ツ?敕ゥツ鳴「テヲツ閉ーテ「ツ?敕」ツ?ョティツソツ氾」ツつ甘・ツ?、
  stack<state> S;
  S.push(EXPR1);
  while (!S.empty()) {
    Type t = S.top().t;
    pll v = S.top().v;
    S.pop();
    if (t == EXPR1) {
      // TERM1テ」ツつ津・ツ?ヲテァツ青?」ツ??「ツ?津」ツ??XPR2テ」ツつ津・ツ?ヲテァツ青?」ツ?ィテ」ツ??」ツ??」ツつ、テ」ツδ。テ」ツδシテ」ツつク
      S.push(state(EXPR2));
      S.push(state(TERM1));
    } else if (t == EXPR2) {
      // nowテ」ツ?ォTERM1テ」ツ?ョテァツオツ静ヲツ楪愿」ツ?古・ツ?・テ」ツ?」テ」ツ?ヲテ」ツ??」ツつ?
      if (s[i] == '|') {
        i++;
        S.push(state(EXPR3, now));
        S.push(state(TERM1));
      }
    } else if (t == EXPR3) {
      // nowテ」ツ?ォTERM1テ」ツ?ョテァツオツ静ヲツ楪愿ッツシツ暗・ツ渉ウテ」ツつェテ」ツδ堙」ツδゥテ」ツδウテ」ツδ嘉ッツシツ嘉」ツ?古・ツ?・テ」ツ?」テ」ツ?ヲテ」ツ??」ツつ?
      // vテ」ツ?ォテ・ツキツヲテ」ツつェテ」ツδ堙」ツδゥテ」ツδウテ」ツδ嘉」ツ?古・ツ?・テ」ツ?」テ」ツ?ヲテ」ツ??」ツつ?
      assign(now, now.first * (v.first + v.second) + now.second * v.first,
             now.second * v.second);
      if (s[i] == '|') {
        i++;
        S.push(state(EXPR3, now));
        S.push(state(TERM1));
      }
    } else if (t == TERM1) {
      S.push(state(TERM2));
      S.push(state(FACT1));
    } else if (t == TERM2) {
      if (s[i] == '&') {
        i++;
        S.push(state(TERM3, now));
        S.push(state(FACT1));
      }
    } else if (t == TERM3) {
      assign(now, now.first * v.first,
             now.first * v.second + now.second * (v.first + v.second));
      if (s[i] == '&') {
        i++;
        S.push(state(TERM3, now));
        S.push(state(FACT1));
      }
    } else if (t == FACT1) {
      if (s[i] == '(') {
        i++;
        S.push(state(FACT2));
        S.push(state(EXPR1));
      } else if (s[i] == '~') {
        i++;
        S.push(state(FACT3));
        S.push(state(FACT1));
      } else {
        // var
        assert(s[i++] == 'x');
        while (isdigit(s[i]))
          i++;
        now = pll(1, 1);
      }
    } else if (t == FACT2) {
      // ()テ」ツ?ョテ・ツセツ古・ツ?ヲテァツ青?
      assert(s[i++] == ')');
    } else if (t == FACT3) {
      // ~テ」ツ?ョテ・ツセツ古・ツ?ヲテァツ青?
      assign(now, now.second, now.first);
    }
  }
  return now.first;
}

int main() {
  string s;
  while (cin >> s) {
    cout << parse(s) << endl;
  }
}

Error: 0

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <valarray>
#include <vector>
using namespace std;

#define REP(i, n) for (int i = 0; i < (int)n; ++i)
#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define ALL(c) (c).begin(), (c).end()
#define chmax(a, b) (a < b ? (a = b, 1) : 0)
#define chmin(a, b) (a > b ? (a = b, 1) : 0)
#define valid(y, x, h, w) (0 <= y && y < h && 0 <= x && x < w)
typedef unsigned long long ll;
typedef pair<int, int> pii;
const int INF = 1 << 29;
const double PI = acos(-1);
const double EPS = 1e-8;

const ll mod = 1e9 + 7;
typedef pair<ll, ll> pll;

void assign(pll &p, ll a, ll b) {
  p.first = a % mod;
  p.second = b % mod;
}

char s[1000002];

pll term(int &);
pll fact(int &);

pll expr(int &id) {
  pll p = term(id);
  while (s[id] == '|') {
    id++;
    pll a = term(id);
    assign(p, p.first * (a.first + a.second) + p.second * a.first,
           p.second * a.second);
  }
  return p;
}

pll term(int &id) {
  pll p = fact(id);
  while (s[id] == '&') {
    id++;
    pll a = fact(id);
    assign(p, p.first * a.first,
           p.first * a.second + p.second * (a.first + a.second));
  }
  return p;
}

pll fact(int &id) {
  pll p;
  if (isalpha(s[id])) {
    id++;
    while (isdigit(s[id]))
      id++;
    p = pll(1, 1);
  } else if (s[id] == '~') {
    id++;
    p = fact(id);
    assign(p, p.second, p.first);
  } else if (s[id] == '(') {
    id++;
    p = expr(id);
    assert(s[id++] == ')');
  } else
    assert(0);
  return p;
}

int main() {
  while (cin >> s) {
    int id = 0;
    pll p = expr(id);
    cout << p.first << endl;
  }
}