//  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 <vector>
#include <istream>
#include <sstream>
#include <iostream>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_multi_pass.hpp>

namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;

// parse list of doubles from input stream
// throw exception (perhaps including filename) on errors
std::vector<double> 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<double> parse(std::istream& input, const std::string& filename)
{
  // iterate over stream input
  typedef std::istreambuf_iterator<char> base_iterator_type;
  base_iterator_type in_begin(input);

  // convert input iterator to forward iterator, usable by spirit parser
  typedef boost::spirit::multi_pass<base_iterator_type> forward_iterator_type;
  forward_iterator_type fwd_begin = boost::spirit::make_default_multi_pass(in_begin);
  forward_iterator_type fwd_end;

  // prepare output
  std::vector<double> output;

  // parse
  bool r = qi::phrase_parse(
    fwd_begin, fwd_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);                                                    // store into this object

  // error detection
  if( !r || fwd_begin != fwd_end )
    throw std::runtime_error("parse error in "+filename);

  // return result
  return output;
}
