fork(6) download
  1. //#define BOOST_SPIRIT_DEBUG
  2. #include <boost/spirit/include/qi.hpp>
  3.  
  4. namespace qi = boost::spirit::qi;
  5.  
  6. typedef std::string Column;
  7. typedef std::vector<Column> Columns;
  8. typedef Columns CsvLine;
  9. typedef std::vector<CsvLine> CsvFile;
  10.  
  11. template <typename It>
  12. struct CsvGrammar : qi::grammar<It, CsvFile(), qi::blank_type>
  13. {
  14. CsvGrammar() : CsvGrammar::base_type(start)
  15. {
  16. static const char colsep = ',';
  17.  
  18. start = -line % qi::eol;
  19. line = column % colsep;
  20. column = quoted | *~qi::char_(colsep);
  21. quoted = '"' >> *("\"\"" | ~qi::char_('"')) >> '"';
  22.  
  23. BOOST_SPIRIT_DEBUG_NODES((start)(line)(column)(quoted));
  24. }
  25. private:
  26. qi::rule<It, CsvFile(), qi::blank_type> start;
  27. qi::rule<It, CsvLine(), qi::blank_type> line;
  28. qi::rule<It, Column(), qi::blank_type> column;
  29. qi::rule<It, std::string()> quoted;
  30. };
  31.  
  32. int main()
  33. {
  34. const std::string s = "1997,Ford,E350,\"ac, abs, moon\",\"\"\"rusty\"\"\",3001.00";
  35.  
  36. typedef std::string::const_iterator It;
  37. It f(s.begin()), l(s.end());
  38. CsvGrammar<It> p;
  39.  
  40. CsvFile parsed;
  41. bool ok = qi::phrase_parse(f,l,p,qi::blank,parsed);
  42.  
  43. if (ok)
  44. {
  45. for (CsvFile::const_iterator lit = parsed.begin(); lit != parsed.end(); ++lit) {
  46. for (Columns::const_iterator cit = lit->begin(); cit != lit->end(); ++cit)
  47. std::cout << '[' << *cit << ']';
  48. std::cout << std::endl;
  49. }
  50. } else
  51. {
  52. std::cout << "Parse failed\n";
  53. }
  54.  
  55. if (f!=l)
  56. std::cout << "Remaining unparsed: '" << std::string(f,l) << "'\n";
  57. }
  58.  
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty