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

#include <bits/stdc++.h>

#define ALL(a) (a).begin(), (a).end()
#define ll long long

const ll MOD = 1000000007;
using namespace std;
string str;

bool isnum(int idx) { return str[idx] >= '0' && str[idx] <= '9'; }

ll dec(ll left, ll right) {
  if (right >= 64 || (1 << right) > left)
    return 0LL;
  else
    return (left >> right);
}

int getend(int idx) {
  int depth = 1;
  idx++;
  for (; depth > 0 && idx < str.size(); idx++) {
    switch (str[idx]) {
    case 'S':
      depth++;
      break;
    case '>':
      if (idx < str.size() - 2 && str[idx + 1] == '>' && str[idx + 2] != '>') {
        idx++;
        break;
      }
      depth--;
      break;
    }
  }
  return idx - 1;
}

ll tonum(int idx) {
  int start = idx, size = 0;
  for (; idx < str.size() && isnum(idx); idx++)
    size++;
  return stoll(str.substr(start, size));
}

ll calc(int start, int end) {
  // cerr << "call" << start << " : " << end << endl;
  bool flag = false;
  ll val = 0;
  for (int i = start; i < end; i++) {
    ll temp = 0;
    if (str[i] == 'S') {
      int cend = getend(i);
      temp = calc(i + 1, cend);
      temp = (temp * temp) % MOD;
      // cerr << "S" << temp << " " << i << endl;
      i = cend;
      // cerr << i << endl;
    } else if (str[i] == '>') {
      // cerr << "flag" << endl;
      flag = true;
      i++;
      continue;
    } else {
      temp = tonum(i);
      // cerr << "N" << temp << " " << i << endl;
      while (i < str.size() && isnum(i))
        i++;
      i--;
    }
    if (flag) {
      val = dec(val, temp);
      // cerr << "D" << val << endl;
      flag = false;
    } else {
      val = temp;
    }
  }
  return val;
}

int main() {
  while (true) {
    str.clear();
    string raw;
    getline(cin, raw);
    for (auto e : raw)
      if (e != ' ' && e != '<')
        str.push_back(e);
    // cerr << str << endl;
    if (str == "#")
      break;
    cout << calc(0, str.size()) << endl;
  }
  return 0;
}


Error: 0
SS12>>2>>
call0
call1
call2
>>2
dec :2
D3 6
>>

Fixed submission:

#include <bits/stdc++.h>

#define ALL(a) (a).begin(), (a).end()
#define ll long long

const ll MOD = 1000000007;
using namespace std;
string str;

bool isnum(char c) { return c >= '0' && c <= '9'; }

ll tonum(int &idx) {
  int start = idx, size = 0;
  for (; idx < str.size() && isnum(str[idx]); idx++)
    size++;
  idx--;
  return stoll(str.substr(start, size));
}

pair<ll, int> calc(int idx) {
  ll val = 0;
  cerr << "call" << idx << endl;
  for (; idx < str.size(); idx++) {
    if (str[idx] == 'S') {
      auto temp = calc(idx + 1);
      val = temp.first;
      assert(idx < temp.second);
      idx = temp.second;
      cerr << "S";
      cerr << val << " " << idx << endl;
    } else if (str[idx] == '>') {
      cerr << str[idx] << str[idx + 1] << str[idx + 2] << endl;
      if (idx < str.size() - 2 && str[idx + 1] == '>' && str[idx + 2] != '>') {
        if (isnum(str[idx + 2])) {
          idx += 2;
          ll dec = tonum(idx);
          cerr << "dec :" << dec << endl;
          val = dec >= 64 ? 0 : (val >> dec);
        } else {
          auto temp = calc(idx + 2);
          val = (val >> temp.first);
          assert(idx <= temp.second);
          idx = temp.second;
        }
        cerr << "D";
        cerr << val << " " << idx << endl;
      } else {
        return make_pair((val * val) % MOD, idx);
      }
    } else if (str[idx] >= '0' && str[idx] <= '9') {
      val = tonum(idx);
    }
  }
  return make_pair(val, idx);
}

int main() {
  while (true) {
    str.clear();
    string raw;
    getline(cin, raw);
    for (auto e : raw)
      if (e != ' ' && e != '<')
        str.push_back(e);
    cerr << str << endl;
    if (str == "#")
      break;
    cout << calc(0).first << endl;
  }
  return 0;
}