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

#include <algorithm>
#include <array>
#include <assert.h>
#include <bitset>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

struct before_main {
  before_main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
  }
} before_main;

#define REP(i, a, b) for (int i = a; i < (int)b; i++)
#define rep(i, n) REP(i, 0, n)
#define all(c) (c).begin(), (c).end()
#define zero(a) memset(a, 0, sizeof a)
#define minus(a) memset(a, -1, sizeof a)
template <class T1, class T2> inline bool minimize(T1 &a, T2 b) {
  return b < a && (a = b, 1);
}
template <class T1, class T2> inline bool maximize(T1 &a, T2 b) {
  return a < b && (a = b, 1);
}
template <class T> ostream &operator<<(ostream &ost, vector<T> const &v) {
  ost << "[";
  rep(i, v.size()) {
    if (i)
      ost << ", ";
    ost << v[i];
  }
  ost << "]";
  return ost;
}

namespace parser {

typedef string::const_iterator Iter;
Iter __begin, __end;
Iter __it;

void remain_dump() {
  cout << "Remain: '" << string(__it, __end) << "'" << endl;
}

void init_iterator(Iter begin, Iter end) {
  __begin = begin;
  __end = end;
  __it = begin;
}

void consume(char expected) {
  assert(__end != __it);
  if (*__it != expected) {
    remain_dump();
    assert(false);
  }
  __it++;
}

bool consume_if(char expected) {
  if (*__it != expected)
    return false;
  consume(expected);
  return true;
}

void unread() {
  assert(__it != __begin);
  __it--;
}

bool eof() { return __it == __end; }

void append(int &tar, char add) {
  tar *= 10;
  tar += add - '0';
}
void append(string &tar, char add) { tar += add; }

enum readable { alphabetical = 1 << 0, integer = 1 << 1 };
enum class lexstat { no_stat = -1, read_eof, success };

lexstat lstat = lexstat::no_stat;

template <class return_type>
return_type lex(readable rd, vector<char> const &skipper = {},
                vector<char> const &excepts = {}) {

  auto can_go = [&](char c) {
    if (find(skipper.begin(), skipper.end(), c) != skipper.end())
      return false;
    if (find(excepts.begin(), excepts.end(), c) != excepts.end())
      return true;
    if ((rd & alphabetical) && isalpha(c))
      return true;
    if ((rd & integer) && isdigit(c))
      return true;
    return false;
  };

  if (!can_go(*__it)) {
    lstat = lexstat::read_eof;
    return return_type{};
  }

  return_type ret{};
  while (can_go(*__it))
    append(ret, *__it), consume(*__it);

  lstat = lexstat::success;

  return ret;
}

void lex_f(string const &force) {
  for (auto c : force)
    consume(c);
}

void lex_f(int force) { lex_f(to_string(force)); }

template <class return_type>
vector<return_type> lex_stream(readable rd, vector<char> const &skipper,
                               vector<char> const &excepts = {}) {
  vector<return_type> ret;
  while (1) {
    auto r = lex<return_type>(rd, skipper, excepts);
    if (lstat == lexstat::read_eof)
      break;
    ret.push_back(r);
    if (find(skipper.begin(), skipper.end(), *__it) != skipper.end()) {
      consume(*__it);
    }
  }
  return ret;
}

bool look_ahead(string const &expected) {
  int n = expected.size();
  int i = 0;
  while (i < n) {
    if (!consume_if(expected[i]))
      break;
    i++;
  }

  if (i == n) {
    while (i--)
      unread();
    return true;
  }

  while (i--)
    unread();
  return false;
}

} // namespace parser
using namespace parser;

#define DEF_PARSER(ast, property_definitions, root_settings)                   \\
  struct ast {                                                                 \\
    property_definitions;                                                      \\
    vector<shared_ptr<ast>> children;                                          \\
  };                                                                           \\
  shared_ptr<ast> parse_##ast(shared_ptr<ast> &p);                             \\
  shared_ptr<const ast> parse_##ast(Iter begin, Iter end) {                    \\
    init_iterator(begin, end);                                                 \\
    auto p = make_shared<xml>();                                               \\
    root_settings;                                                             \\
    return parse_##ast(p);                                                     \\
  }

#define PARSE(ast, tar) parse_##ast(begin(tar), end(tar))

#define PARSER_IMPL(ast, start_cond)                                           \\
  shared_ptr<ast> parse_##ast(shared_ptr<ast> &p) {                            \\
    while (!eof()) {                                                           \\
      if (start_cond) {
#define HEAD(str) look_ahead(str)
#define TERMINATE return p;
#define CHANCE(cond)                                                           \\
  }                                                                            \\
  else if (cond) {

#define END_PARSER_IMPL                                                        \\
  }                                                                            \\
  }                                                                            \\
  return p;                                                                    \\
  }

#define prop(pr) p->pr
#define cprop(pr) c->pr

#define RECUR(ast, property_settings)                                          \\
  auto c = make_shared<ast>();                                                 \\
  property_settings;                                                           \\
  p->children.push_back(c);                                                    \\
  parse_##ast(c);                                                              \\
  continue;

#define ast_ref(const_ast) shared_ptr<const const_ast> const &__ast_ref_p
#define enumerate_children(c) for (auto &&c : __ast_ref_p->children)

#define ref_prop(pr) __ast_ref_p->pr

///////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////

DEF_PARSER(xml, string tag; vector<int> nums;, prop(tag) = "OUT OF MAIN PANEL")

PARSER_IMPL(xml, HEAD("</"))
lex_f("</" + p->tag + ">");
TERMINATE CHANCE(HEAD("<"))
    RECUR(xml, cprop(tag) = lex<string>(alphabetical, {}, {'<', '>'});
          cprop(tag) = c->tag.substr(1, c->tag.size() - 2);
          cprop(nums) = lex_stream<int>(integer, {','});) END_PARSER_IMPL

    pair<string, int> dfs(ast_ref(xml), int x, int y) {
  enumerate_children(c) if (c->nums[0] <= x && c->nums[1] <= y &&
                            x <= c->nums[2] &&
                            y <= c->nums[3]) return dfs(c, x, y);

  return {ref_prop(tag), ref_prop(children.size())};
}

int main() {

  for (int T; cin >> T;) {
    string str;
    cin >> str;
    auto root = PARSE(xml, str);
    while (T--) {
      int x, y;
      cin >> x >> y;
      auto r = dfs(root, x, y);
      cout << r.first << " " << r.second << endl;
    }
  }
  return 0;
}

Error: -6
f4429321-5f82-42a7-b9e8-7ad4222befa1.out: /home/alex/Documents/bug-detection/input/Project_CodeNet/data/p00617/C++/s204244062.cpp:57: void parser::consume(char): Assertion `false' failed.


Fixed submission:

#include <algorithm>
#include <array>
#include <assert.h>
#include <bitset>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

struct before_main {
  before_main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
  }
} before_main;

#define REP(i, a, b) for (int i = a; i < (int)b; i++)
#define rep(i, n) REP(i, 0, n)
#define all(c) (c).begin(), (c).end()
#define zero(a) memset(a, 0, sizeof a)
#define minus(a) memset(a, -1, sizeof a)
template <class T1, class T2> inline bool minimize(T1 &a, T2 b) {
  return b < a && (a = b, 1);
}
template <class T1, class T2> inline bool maximize(T1 &a, T2 b) {
  return a < b && (a = b, 1);
}
template <class T> ostream &operator<<(ostream &ost, vector<T> const &v) {
  ost << "[";
  rep(i, v.size()) {
    if (i)
      ost << ", ";
    ost << v[i];
  }
  ost << "]";
  return ost;
}

namespace parser {

typedef string::const_iterator Iter;
Iter __begin, __end;
Iter __it;

void remain_dump() {
  cout << "Remain: '" << string(__it, __end) << "'" << endl;
}

void init_iterator(Iter begin, Iter end) {
  __begin = begin;
  __end = end;
  __it = begin;
}

void consume(char expected) {
  assert(__end != __it);
  if (*__it != expected) {
    remain_dump();
    assert(false);
  }
  __it++;
}

bool consume_if(char expected) {
  if (*__it != expected)
    return false;
  consume(expected);
  return true;
}

void unread() {
  assert(__it != __begin);
  __it--;
}

bool eof() { return __it == __end; }

void append(int &tar, char add) {
  tar *= 10;
  tar += add - '0';
}
void append(string &tar, char add) { tar += add; }

enum readable { alphabetical = 1 << 0, integer = 1 << 1 };
enum class lexstat { no_stat = -1, read_eof, success };

lexstat lstat = lexstat::no_stat;

template <class return_type>
return_type lex(readable rd, vector<char> const &skipper = {},
                vector<char> const &excepts = {}) {

  auto can_go = [&](char c) {
    if (find(skipper.begin(), skipper.end(), c) != skipper.end())
      return false;
    if (find(excepts.begin(), excepts.end(), c) != excepts.end())
      return true;
    if ((rd & alphabetical) && isalpha(c))
      return true;
    if ((rd & integer) && isdigit(c))
      return true;
    return false;
  };

  if (!can_go(*__it)) {
    lstat = lexstat::read_eof;
    return return_type{};
  }

  return_type ret{};
  while (can_go(*__it))
    append(ret, *__it), consume(*__it);

  lstat = lexstat::success;

  return ret;
}

void lex_f(string const &force) {
  for (auto c : force)
    consume(c);
}

void lex_f(int force) { lex_f(to_string(force)); }

template <class return_type>
vector<return_type> lex_stream(readable rd, vector<char> const &skipper,
                               vector<char> const &excepts = {}) {
  vector<return_type> ret;
  while (1) {
    auto r = lex<return_type>(rd, skipper, excepts);
    if (lstat == lexstat::read_eof)
      break;
    ret.push_back(r);
    if (find(skipper.begin(), skipper.end(), *__it) != skipper.end()) {
      consume(*__it);
    }
  }
  return ret;
}

bool look_ahead(string const &expected) {
  int n = expected.size();
  int i = 0;
  while (i < n) {
    if (!consume_if(expected[i]))
      break;
    i++;
  }

  if (i == n) {
    while (i--)
      unread();
    return true;
  }

  while (i--)
    unread();
  return false;
}

} // namespace parser
using namespace parser;

#define DEF_PARSER(ast, property_definitions, root_settings)                   \\
  struct ast {                                                                 \\
    property_definitions;                                                      \\
    vector<shared_ptr<ast>> children;                                          \\
  };                                                                           \\
  shared_ptr<ast> parse_##ast(shared_ptr<ast> &p);                             \\
  shared_ptr<const ast> parse_##ast(Iter begin, Iter end) {                    \\
    init_iterator(begin, end);                                                 \\
    auto p = make_shared<xml>();                                               \\
    root_settings;                                                             \\
    return parse_##ast(p);                                                     \\
  }

#define PARSE(ast, tar) parse_##ast(begin(tar), end(tar))

#define PARSER_IMPL(ast, start_cond)                                           \\
  shared_ptr<ast> parse_##ast(shared_ptr<ast> &p) {                            \\
    while (!eof()) {                                                           \\
      if (start_cond) {
#define HEAD(str) look_ahead(str)
#define CHANCE(cond)                                                           \\
  return p;                                                                    \\
  }                                                                            \\
  else if (cond) {

#define END_PARSER_IMPL                                                        \\
  }                                                                            \\
  }                                                                            \\
  return p;                                                                    \\
  }

#define prop(pr) p->pr
#define cprop(pr) c->pr

#define RECUR(ast, property_settings)                                          \\
  auto c = make_shared<ast>();                                                 \\
  property_settings;                                                           \\
  p->children.push_back(c);                                                    \\
  parse_##ast(p);

#define ast_ref(const_ast) shared_ptr<const const_ast> const &__ast_ref_p
#define enumerate_children(c) for (auto &&c : __ast_ref_p->children)

#define ref_prop(pr) __ast_ref_p->pr

///////////////////////////////////////////////////////////////////////////////////////////////////////////////

DEF_PARSER(xml, string tag; vector<int> nums;, prop(tag) = "OUT OF MAIN PANEL")

PARSER_IMPL(xml, HEAD("</"))
lex_f("</" + p->tag + ">");
CHANCE(HEAD("<"))
RECUR(xml, cprop(tag) = lex<string>(alphabetical, {}, {'<', '>'});
      cprop(tag) = c->tag.substr(1, c->tag.size() - 2);
      cprop(nums) = lex_stream<int>(integer, {','});)
END_PARSER_IMPL

pair<string, int> dfs(ast_ref(xml), int x, int y) {
  enumerate_children(c) if (c->nums[0] <= x && c->nums[1] <= y &&
                            x <= c->nums[2] &&
                            y <= c->nums[3]) return dfs(c, x, y);

  return {ref_prop(tag), ref_prop(children.size())};
}

int main() {

  for (int T; cin >> T;) {
    string str;
    cin >> str;
    auto root = PARSE(xml, str);
    while (T--) {
      int x, y;
      cin >> x >> y;
      auto r = dfs(root, x, y);
      cout << r.first << " " << r.second << endl;
    }
  }
  return 0;
}