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

#include <algorithm>
#include <cassert>
#include <cctype>
#include <cstdint>
#include <cstdio>
#include <deque>
#include <string>
#include <vector>

void preprocess(const std::string &s, std::string &t) {
  std::string u;
  for (char ch : s)
    if (!isspace(ch))
      u += ch;

  t.clear();
  for (size_t i = 0; i < u.length(); ++i) {
    if (u[i] == 'S') {
      ++i;
      assert(u[i] == '<');
      t += '(';
    } else if (isdigit(u[i])) {
      t += u[i];
    } else if (u[i] == '>') {
      if (i + 2 < u.length() && u[i + 1] == '>') {
        if (isdigit(u[i + 2])) {
          t += '>';
          t += u[i += 2];
        } else if (u[i + 2] == 'S') {
          t += '>';
          ++i;
        } else {
          t += ')';
        }
      } else {
        t += ')';
      }
    } else {
      assert(false);
    }
  }
}

const intmax_t MOD = 1e9 + 7;

intmax_t parse(const std::string &s, size_t &i, size_t preced = 0) {
  if (preced == 1) {
    if (s[i] == '(') {
      intmax_t res = parse(s, ++i, 0);
      assert(s[i] == ')');
      ++i;
      return res * res % MOD;
    } else if (isdigit(s[i])) {
      intmax_t res = s[i] - '0';
      while (++i < s.length() && isdigit(s[i]))
        res = res * 10 + s[i] - '0';
      return res;
    }
    assert(false);
  }
  intmax_t lhs = parse(s, i, preced + 1);
  while (i < s.length()) {
    char op = s[i];
    if (op != '>')
      break;
    intmax_t rhs = parse(s, ++i, preced + 1);
    (rhs < 63 ? lhs >>= rhs : lhs = 0);
  }
  return lhs;
}

int testcase_ends() {
  char buf[2000010];
  fgets(buf, sizeof buf, stdin);
  std::string s = std::move(buf), t;
  if (s == "#\\n")
    return 1;

  preprocess(s, t);
  size_t i = 0;
  printf("%jd\\n", parse(t, i));
  return 0;
}

int main() {
  while (!testcase_ends()) {
  }
}


Error: 0
t: ((12>2))
t: 123>1>1
t: 1000000000>129
t: (((((2)))))
t: (((2013)>11)>10)


Fixed submission:

#include <algorithm>
#include <cassert>
#include <cctype>
#include <cstdint>
#include <cstdio>
#include <deque>
#include <string>
#include <vector>

void preprocess(const std::string &s, std::string &t) {
  std::string u;
  for (char ch : s)
    if (!isspace(ch))
      u += ch;

  for (size_t i = 0; i < u.length(); ++i) {
    if (u[i] == 'S') {
      ++i;
      assert(u[i] == '<');
      t += '(';
    } else if (isdigit(u[i])) {
      t += u[i];
    } else if (u[i] == '>') {
      if (i + 2 < u.length() && u[i + 1] == '>' && isdigit(u[i + 2])) {
        t += '>';
        t += u[i += 2];
      } else {
        t += ')';
      }
    } else {
      assert(false);
    }
  }
  fprintf(stderr, "t: %s\\n", t.c_str());
}

const intmax_t MOD = 1e9 + 7;

intmax_t parse(const std::string &s, size_t &i, size_t preced = 0) {
  if (preced == 1) {
    if (s[i] == '(') {
      intmax_t res = parse(s, ++i, 0);
      assert(s[i] == ')');
      ++i;
      return res * res % MOD;
    } else if (isdigit(s[i])) {
      intmax_t res = s[i] - '0';
      while (++i < s.length() && isdigit(s[i]))
        res = res * 10 + s[i] - '0';
      return res;
    }
    assert(false);
  }
  intmax_t lhs = parse(s, i, preced + 1);
  while (i < s.length()) {
    char op = s[i];
    if (op != '>')
      break;
    intmax_t rhs = parse(s, ++i, preced + 1);
    (rhs < 63 ? lhs >>= rhs : lhs = 0);
  }
  return lhs;
}

int testcase_ends() {
  char buf[2000010];
  fgets(buf, sizeof buf, stdin);
  std::string s = std::move(buf), t;
  if (s == "#\\n")
    return 1;

  preprocess(s, t);
  size_t i = 0;
  printf("%jd\\n", parse(t, i));
  return 0;
}

int main() {
  while (!testcase_ends()) {
  }
}