IntegerType parse_ascii_integer(TokenStream & stream) { if (!stream.peek()) throw std::runtime_error("eof"); if (!ascii_digit_value(*stream.peek())) { throw std::runtime_error("not at a number!"); } IntegerType toret = 0; while (true) { auto inb = stream.peek(); if (!inb) break; auto digit_val = ascii_digit_value(*inb); if (!digit_val) break; auto oldtoret = toret; toret = toret * 10 + *digit_val; if (toret < oldtoret) { throw std::runtime_error("overflow occured"); } stream.skip(); } return toret; }
std::vector<typename std::decay<decltype(*std::declval<TokenStream>().peek())>::type> read_token_vector(TokenStream & stream, opt::optional<Token> term, opt::optional<size_t> max_amt, bool drop_term = false) { std::vector<typename std::decay<decltype(*std::declval<TokenStream>().peek())>::type> toret; for (size_t i = 0; !max_amt || i < *max_amt; ++i) { auto mB = stream.peek(); if (!mB || (term && *mB == *term)) { if (drop_term) stream.skip(); break; } toret.push_back(*mB); stream.skip(); } return toret; }
void expect(TokenStream & stream, Token expected) { auto maybe_token = stream.peek(); if (!maybe_token || *maybe_token != expected) { throw std::runtime_error("Failed expect"); } stream.skip(); }
void skip_token(TokenStream & stream, Token token) { while (true) { auto inb = stream.peek(); if (!inb || *inb != token) break; stream.skip(); } }