Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define BOOST_SPIRIT_DEBUG
- #include <iostream>
- #include <boost/spirit/include/qi.hpp>
- #include <boost/spirit/include/phoenix.hpp>
- #include <string>
- #include <vector>
- namespace qi = boost::spirit::qi;
- namespace phx = boost::phoenix;
- using std::string;
- enum LineItems {
- NAME, AGE, UNUSED
- };
- struct CsvLine {
- string name;
- int age;
- };
- using Column = std::string;
- using Columns = std::vector<Column>;
- using CsvFile = std::vector<CsvLine>;
- template<typename It>
- struct CsvGrammar: qi::grammar<It, CsvFile(), qi::locals<std::vector<LineItems>>, qi::blank_type> {
- CsvGrammar() :
- CsvGrammar::base_type(start) {
- using namespace qi;
- static const char colsep = ',';
- start = qi::omit[header[qi::_a = qi::_1]] >> eol >> line(_a) % eol;
- header = (lit("Name")[phx::push_back(phx::ref(qi::_val), LineItems::NAME)]
- | lit("Age")[phx::push_back(phx::ref(qi::_val), LineItems::AGE)]
- | column[phx::push_back(phx::ref(qi::_val), LineItems::UNUSED)]) % colsep;
- line = (column % colsep)[phx::bind(&CsvGrammar<It>::convertFunc, this, qi::_1, qi::_r1,
- qi::_val)];
- column = quoted | *~char_(",\n");
- quoted = '"' >> *("\"\"" | ~char_("\"\n")) >> '"';
- BOOST_SPIRIT_DEBUG_NODES((header)(column)(quoted));
- }
- void convertFunc(const std::vector<string>& columns, const std::vector<LineItems>& positions, CsvLine &csvLine) {
- int i =0;
- for (LineItems position : positions) {
- switch(position){
- case NAME:
- csvLine.name = columns[i];
- break;
- case AGE:
- csvLine.age = atoi(columns[i].c_str());
- break;
- }
- i++;
- }
- }
- private:
- qi::rule<It, CsvFile(), qi::locals<std::vector<LineItems>>, qi::blank_type> start;
- qi::rule<It, std::vector<LineItems>(), qi::blank_type> header;
- qi::rule<It, CsvLine(std::vector<LineItems>), qi::blank_type> line;
- qi::rule<It, Column(), qi::blank_type> column;
- qi::rule<It, std::string()> quoted;
- qi::rule<It, qi::blank_type> empty;
- };
- int main() {
- const std::string s = "Surname,Name,Age,\nJohn,Doe,32\nMark,Smith,43";
- auto f(begin(s)), l(end(s));
- CsvGrammar<std::string::const_iterator> p;
- CsvFile parsed;
- bool ok = qi::phrase_parse(f, l, p, qi::blank, parsed);
- if (ok) {
- for (CsvLine line : parsed) {
- std::cout << '[' << line.name << ']' << '[' << line.age << ']';
- std::cout << std::endl;
- }
- } else {
- std::cout << "Parse failed\n";
- }
- if (f != l)
- std::cout << "Remaining unparsed: '" << std::string(f, l) << "'\n";
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement