51 lines
1.4 KiB
C++
51 lines
1.4 KiB
C++
#ifndef AOCPP_PARSING_HPP_
|
|
#define AOCPP_PARSING_HPP_
|
|
|
|
#include <string>
|
|
#include <iostream>
|
|
#include <iterator>
|
|
#include <vector>
|
|
|
|
#include <boost/spirit/home/qi.hpp>
|
|
|
|
namespace aocpp {
|
|
|
|
auto SplitOn(std::string const& stuff, std::string const& sep) -> std::vector<std::string>;
|
|
|
|
/// Parse the complete input stream according to the rules defined in 'Grammar'.
|
|
/// Throws: std::runtime_error on failed parse
|
|
template <typename G>
|
|
auto ParseGrammar(G const& grammar, std::istream & in) -> typename G::start_type::attr_type
|
|
{
|
|
namespace qi = boost::spirit::qi;
|
|
auto result = typename G::start_type::attr_type {};
|
|
auto const content = std::string{std::istreambuf_iterator{in}, {}};
|
|
auto b = content.begin(); // updated on successful parse
|
|
auto const e = content.end();
|
|
|
|
if (!qi::parse(b, e, grammar, result) || b != e) {
|
|
throw std::runtime_error{"Bad input file: " + content};
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
template <typename G>
|
|
auto ParseGrammar_(G const& grammar, std::istream & in) -> typename G::start_type::attr_type
|
|
{
|
|
namespace qi = boost::spirit::qi;
|
|
auto result = typename G::start_type::attr_type {};
|
|
auto const content = std::string{std::istreambuf_iterator{in}, {}};
|
|
auto b = content.begin(); // updated on successful parse
|
|
auto const e = content.end();
|
|
|
|
if (!qi::phrase_parse(b, e, grammar, qi::ascii::space, result) || b != e) {
|
|
throw std::runtime_error{"Bad input file: " + content};
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
}
|
|
|
|
#endif |