// Copyright (c) 2010 Peter Schueller // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #include #include #include #include #include #include #include namespace qi = boost::spirit::qi; namespace ascii = boost::spirit::ascii; namespace classic = boost::spirit::classic; // parse list of doubles from input stream // throw exception (perhaps including filename) on errors std::vector parse(std::istream& input, const std::string& filename); // main function int main(int, char**) { try { parse(std::cin, "STDIN"); } catch(const std::exception& e) { std::cerr << "Exception: " << e.what() << std::endl; return -1; } return 0; } // implementation std::vector parse(std::istream& input, const std::string& filename) { // iterate over stream input typedef std::istreambuf_iterator base_iterator_type; base_iterator_type in_begin(input); // convert input iterator to forward iterator, usable by spirit parser typedef boost::spirit::multi_pass forward_iterator_type; forward_iterator_type fwd_begin = boost::spirit::make_default_multi_pass(in_begin); forward_iterator_type fwd_end; // wrap forward iterator with position iterator, to record the position typedef classic::position_iterator2 pos_iterator_type; pos_iterator_type position_begin(fwd_begin, fwd_end, filename); pos_iterator_type position_end; // prepare output std::vector output; // parse try { qi::phrase_parse( position_begin, position_end, // iterators over input qi::double_ > *(',' > qi::double_) >> qi::eoi, // recognize list of doubles ascii::space | '#' >> *(ascii::char_ - qi::eol) >> qi::eol, // comment skipper output); // doubles are stored into this object } catch(const qi::expectation_failure& e) { const classic::file_position_base& pos = e.first.get_position(); std::stringstream msg; msg << "parse error at file " << pos.file << " line " << pos.line << " column " << pos.column << std::endl << "'" << e.first.get_currentline() << "'" << std::endl << std::setw(pos.column) << " " << "^- here"; throw std::runtime_error(msg.str()); } // return result return output; }