| 1 | // Copyright (c) 2010 Peter Schueller |
|---|---|
| 2 | // Copyright (c) 2001-2010 Hartmut Kaiser |
| 3 | // |
| 4 | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
| 5 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
| 6 | |
| 7 | #include <vector> |
| 8 | #include <istream> |
| 9 | #include <sstream> |
| 10 | #include <iostream> |
| 11 | |
| 12 | #include <boost/spirit/include/qi.hpp> |
| 13 | #include <boost/spirit/include/support_multi_pass.hpp> |
| 14 | |
| 15 | #include <boost/core/lightweight_test.hpp> |
| 16 | |
| 17 | namespace qi = boost::spirit::qi; |
| 18 | namespace ascii = boost::spirit::ascii; |
| 19 | |
| 20 | std::vector<double> parse(std::istream& input) |
| 21 | { |
| 22 | // iterate over stream input |
| 23 | typedef std::istreambuf_iterator<char> base_iterator_type; |
| 24 | base_iterator_type in_begin(input); |
| 25 | |
| 26 | // convert input iterator to forward iterator, usable by spirit parser |
| 27 | typedef boost::spirit::multi_pass<base_iterator_type> forward_iterator_type; |
| 28 | forward_iterator_type fwd_begin = boost::spirit::make_default_multi_pass(i&: in_begin); |
| 29 | forward_iterator_type fwd_end; |
| 30 | |
| 31 | // prepare output |
| 32 | std::vector<double> output; |
| 33 | |
| 34 | // parse |
| 35 | bool r = qi::phrase_parse( |
| 36 | first&: fwd_begin, last: fwd_end, // iterators over input |
| 37 | expr: qi::double_ >> *(',' >> qi::double_) >> qi::eoi, // recognize list of doubles |
| 38 | skipper: ascii::space | '#' >> *(ascii::char_ - qi::eol) >> qi::eol, // comment skipper |
| 39 | attr&: output); // doubles are stored into this object |
| 40 | |
| 41 | // error detection |
| 42 | if( !r || fwd_begin != fwd_end ) |
| 43 | throw std::runtime_error("parse error"); |
| 44 | |
| 45 | // return result |
| 46 | return output; |
| 47 | } |
| 48 | |
| 49 | int main() |
| 50 | { |
| 51 | try { |
| 52 | std::stringstream str("1.0,2.0\n"); |
| 53 | std::vector<double> values = parse(input&: str); |
| 54 | BOOST_TEST(values.size() == 2 && values[0] == 1.0 && values[1] == 2.0); |
| 55 | } |
| 56 | catch(std::exception const&) { |
| 57 | BOOST_TEST(false); |
| 58 | } |
| 59 | return boost::report_errors(); |
| 60 | } |
| 61 |
