This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub suisen-cp/cp-library-cpp
#include "library/icpc/parsing.hpp"
#include <iostream> #include <optional> #include <string> namespace suisen::parsing { using State = std::string::const_iterator; struct ParseError { ParseError(const std::string& message = "") { std::cerr << message << std::endl; } }; namespace internal { void print_rest_of_string(State it) { std::cerr << "Rest string is '"; while (*it) std::cerr << *it++; std::cerr << "'" << std::endl; } } void consume(State& it, char expected) { if (*it == expected) { *it++; } else { std::cerr << "Expected '" << expected << "' but got '" << *it << "'" << std::endl; internal::print_rest_of_string(it); throw ParseError{}; } } bool in(const State& it, char l, char r) { return l <= *it and *it <= r; } bool is(const State& it, char c) { return *it == c; } void assert_range(const State& it, char lo, char hi) { if (not in(it, lo, hi)) { std::cerr << "Expected [" << lo << "-" << hi << "] but got '" << *it << "'" << std::endl; internal::print_rest_of_string(it); throw ParseError{}; } } void assert_exact(const State& it, char c) { if (not is(it, c)) { std::cerr << "Expected '" << c << "' but got '" << *it << "'" << std::endl; internal::print_rest_of_string(it); throw ParseError{}; } } long long nonnegative_number(State& it) { long long res = 0; assert_range(it, '0', '9'); while (in(it, '0', '9')) res = res * 10 + (*it++ - '0'); return res; } long long number(State& it) { long long res = 0; bool neg = false; while (is(it, '-')) neg = not neg, consume(it, '-'); while (in(it, '0', '9')) res = res * 10 + (*it++ - '0'); if (neg) res = -res; return res; } namespace normal_expression { namespace internal { long long expr(State& it); long long term(State& it); long long factor(State& it); long long expr(State& it) { long long res = term(it); while (true) { if (*it == '+') { consume(it, '+'); res = res + term(it); } else if (*it == '-') { consume(it, '-'); res = res - term(it); } else break; } return res; } long long term(State& it) { long long res = factor(it); while (true) { if (*it == '*') { consume(it, '*'); res = res * factor(it); } else if (*it == '/') { consume(it, '/'); res = res / factor(it); } else break; } return res; } long long factor(State& it) { bool neg = false; while (is(it, '-')) neg = not neg, consume(it, '-'); long long res; if (is(it, '(')) { consume(it, '('); res = expr(it); consume(it, ')'); } else { res = nonnegative_number(it); } if (neg) res = -res; return res; } } long long parse(State& it) { return internal::expr(it); } } }
#line 1 "library/icpc/parsing.hpp" #include <iostream> #include <optional> #include <string> namespace suisen::parsing { using State = std::string::const_iterator; struct ParseError { ParseError(const std::string& message = "") { std::cerr << message << std::endl; } }; namespace internal { void print_rest_of_string(State it) { std::cerr << "Rest string is '"; while (*it) std::cerr << *it++; std::cerr << "'" << std::endl; } } void consume(State& it, char expected) { if (*it == expected) { *it++; } else { std::cerr << "Expected '" << expected << "' but got '" << *it << "'" << std::endl; internal::print_rest_of_string(it); throw ParseError{}; } } bool in(const State& it, char l, char r) { return l <= *it and *it <= r; } bool is(const State& it, char c) { return *it == c; } void assert_range(const State& it, char lo, char hi) { if (not in(it, lo, hi)) { std::cerr << "Expected [" << lo << "-" << hi << "] but got '" << *it << "'" << std::endl; internal::print_rest_of_string(it); throw ParseError{}; } } void assert_exact(const State& it, char c) { if (not is(it, c)) { std::cerr << "Expected '" << c << "' but got '" << *it << "'" << std::endl; internal::print_rest_of_string(it); throw ParseError{}; } } long long nonnegative_number(State& it) { long long res = 0; assert_range(it, '0', '9'); while (in(it, '0', '9')) res = res * 10 + (*it++ - '0'); return res; } long long number(State& it) { long long res = 0; bool neg = false; while (is(it, '-')) neg = not neg, consume(it, '-'); while (in(it, '0', '9')) res = res * 10 + (*it++ - '0'); if (neg) res = -res; return res; } namespace normal_expression { namespace internal { long long expr(State& it); long long term(State& it); long long factor(State& it); long long expr(State& it) { long long res = term(it); while (true) { if (*it == '+') { consume(it, '+'); res = res + term(it); } else if (*it == '-') { consume(it, '-'); res = res - term(it); } else break; } return res; } long long term(State& it) { long long res = factor(it); while (true) { if (*it == '*') { consume(it, '*'); res = res * factor(it); } else if (*it == '/') { consume(it, '/'); res = res / factor(it); } else break; } return res; } long long factor(State& it) { bool neg = false; while (is(it, '-')) neg = not neg, consume(it, '-'); long long res; if (is(it, '(')) { consume(it, '('); res = expr(it); consume(it, ')'); } else { res = nonnegative_number(it); } if (neg) res = -res; return res; } } long long parse(State& it) { return internal::expr(it); } } }