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

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
constexpr ll MOD = 1000000007;

class SyntaxAnalysis {
public:
  SyntaxAnalysis(const string &S) : S{S} {}
  ll Expression() { return pos = 0, expression(); }

private:
  static ll sf(const ll n, const ll k) { return k >= 64 ? 0 : n >> k; }
  static ll sq(const ll n) { return n * n % MOD; }
  ll number() {
    ll ans = 0;
    for (; pos < S.size() and isdigit(S[pos]); pos++) {
      ans = ans * 10 + S[pos] - '0';
    }
    return ans;
  }
  ll factor() {
    if (S[pos] == '<') {
      ll ans;
      return pos++, ans = sq(expression()), pos++, ans;
    } else {
      return number();
    }
  }
  ll term() {
    ll ans = factor();
    for (ll f = 0; pos < S.size() and S[pos] == '%';) {
      pos++, f = factor(), ans = sf(ans, f);
    }
    return ans;
  }
  ll expression() { return term(); }
  int pos = 0;
  string S;
};

int main() {
  while (true) {
    auto input = []() {
      string s;
      getline(cin, s);
      string ans;
      for (ll i = s.size() - 1, st = 0, v = false; i >= 0; i--) {
        const char c = s[i];
        if (isdigit(c)) {
          ans.push_back(c), v = true;
        }
        if (c == '>') {
          if (v) {
            ans.push_back('%'), v = false, i--;
          } else {
            ans.push_back('>'), st++;
          }
        }
        if (c == '<') {
          ans.push_back('<'), v = true, st--;
        }
      }
      reverse(ans.begin(), ans.end());
      return ans;
    };
    const string S = input();
    if (S.empty()) {
      break;
    }
    SyntaxAnalysis sy(S);
    cout << sy.Expression() << endl;
  }
  return 0;
}


Error: 0
sub = 3
sub = 9
sub = 2
sub = 4
sub = 16
sub = 256
sub = 65536
sub = 2013
sub = 1978
sub = 3820


Fixed submission:

#include <bits/stdc++.h>
#define show(x) cerr << #x << " = " << (x) << endl
using namespace std;
constexpr int MOD = 1000000007;
inline int sf(const int k, const int n) { return k > 32 ? 0 : n >> k; }
inline int sq(const long long n) { return n * n % MOD; }
template <typename Functor> struct fix_type {
  Functor functor;
  template <typename... Args>
  decltype(auto) operator()(Args &&...args) const & {
    return functor(functor, std::forward<Args>(args)...);
  }
};
template <typename Functor>
fix_type<typename std::decay<Functor>::type> fix(Functor &&functor) {
  return {std::forward<Functor>(functor)};
}

int main() {
  while (true) {
    auto input = []() {
      string s;
      getline(cin, s);
      string ans;
      for (int i = s.size() - 1, st = 0, v = false; i >= 0; i--) {
        const char c = s[i];
        if (isdigit(c)) {
          ans.push_back(c), v = true;
        }
        if (c == '>') {
          if (v) {
            ans.push_back('%'), v = false, i--;
          } else {
            ans.push_back('<'), st++;
          }
        }
        if (c == '<') {
          ans.push_back('>'), v = true, st--;
        }
      }
      return ans;
    };
    const string S = input();
    if (S.empty()) {
      break;
    }
    // show(S);
    int pos = 0, ans = 0;
    auto dfs = fix([&](auto &&self) -> int {
      if (pos >= S.size()) {
        return ans;
      }
      const char c = S[pos];
      if (c == '<') {
        pos++;
        const int sub = self(self);
        show(sub);
        ans = sq(sub);
        return self(self);
      } else if (c == '%') {
        pos++;
        const int prev = ans;
        const int next = self(self);
        ans = sf(prev, next);
        return self(self);
      } else if (isdigit(c)) {
        int num = 0;
        for (int d = 1; pos < S.size() and isdigit(S[pos]); d *= 10, pos++) {
          num += d * (S[pos] - '0');
        }
        ans = num;
        return self(self);
      } else {
        pos++;
        return self(self);
      }
    });
    dfs();
    cout << ans << endl;
  }
  return 0;
}