#include <boost/fusion/adapted/std_pair.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
typedef std::string column_name_t;
enum sql_faggregate
{
AVG,
// ....
SUM,
};
typedef std::pair<column_name_t, int/*sql_faggregate*/> column_and_aggregate;
typedef std::vector<column_and_aggregate> column_and_aggregate_container;
namespace parsers
{
typedef std::string::const_iterator iterator;
qi::rule< iterator, column_name_t() > quoted_string =
qi::lexeme["\"" >> +~qi::char_("\"") >> "\""];
qi::rule< iterator, column_and_aggregate(), qi::space_type > agg_pair =
quoted_string [ phx::at_c<0>(qi::_val) = qi::_1 ]
> ':'
// A rule validation technic is used below.
> qi::int_[qi::_pass = (qi::_1 >=AVG && qi::_1<=SUM), phx::at_c<1>(qi::_val) = qi::_1];//::boost::bind( &apply_col_and_aggr_visitor, qi::_val, qi::_1 )];
qi::rule< iterator, column_and_aggregate_container(), qi::space_type > aggregates_parser =
'{'
> agg_pair/*[phoenix::push_back(qi::_val, qi::_1)]*/ % ',' // N.B.!!! list-redux technic
> '}';
}
bool doParse(const std::string& input)
{
using namespace parsers;
auto f(begin(input)), l(end(input));
//parser<iterator, qi::space_type> p;
column_and_aggregate_container data;
try
{
bool ok = qi::phrase_parse(f,l,aggregates_parser,qi::space,data);
if (ok)
{
std::cout << "parse success\n";
for (auto& pair : data)
std::cout << "result: '" << pair.first << "' : " << (int) pair.second << "\n";
}
else std::cerr << "parse failed: '" << std::string(f,l) << "'\n";
if (f!=l) std::cerr << "trailing unparsed: '" << std::string(f,l) << "'\n";
return ok;
}
catch(const qi::expectation_failure<iterator>& e)
{
std::string frag(e.first, e.last);
std::cerr << e.what() << "'" << frag << "'\n";
}
return false;
}
int main()
{
//bool ok = doParse("{ 'column 1' : 1, 'column 2' : 0, 'column 3' : 1 }");
doParse("{ \"column 1\" : 1, \"column 2\" : 0, \"column 3\" : 1 }");
//return ok? 0 : 255;
}
I2luY2x1ZGUgPGJvb3N0L2Z1c2lvbi9hZGFwdGVkL3N0ZF9wYWlyLmhwcD4KI2luY2x1ZGUgPGJvb3N0L3NwaXJpdC9pbmNsdWRlL3FpLmhwcD4KI2luY2x1ZGUgPGJvb3N0L3NwaXJpdC9pbmNsdWRlL3Bob2VuaXguaHBwPgojaW5jbHVkZSA8Ym9vc3Qvc3Bpcml0L2luY2x1ZGUvcGhvZW5peF9mdXNpb24uaHBwPgoKbmFtZXNwYWNlIHFpICAgID0gYm9vc3Q6OnNwaXJpdDo6cWk7Cm5hbWVzcGFjZSBwaHggICA9IGJvb3N0OjpwaG9lbml4OwoKdHlwZWRlZiBzdGQ6OnN0cmluZyBjb2x1bW5fbmFtZV90OwoKZW51bSBzcWxfZmFnZ3JlZ2F0ZQp7CiAgICBBVkcsCiAgICAvLyAuLi4uCiAgICBTVU0sCn07Cgp0eXBlZGVmIHN0ZDo6cGFpcjxjb2x1bW5fbmFtZV90LCBpbnQvKnNxbF9mYWdncmVnYXRlKi8+IGNvbHVtbl9hbmRfYWdncmVnYXRlOwp0eXBlZGVmIHN0ZDo6dmVjdG9yPGNvbHVtbl9hbmRfYWdncmVnYXRlPiBjb2x1bW5fYW5kX2FnZ3JlZ2F0ZV9jb250YWluZXI7CgpuYW1lc3BhY2UgcGFyc2Vycwp7CiAgICB0eXBlZGVmIHN0ZDo6c3RyaW5nOjpjb25zdF9pdGVyYXRvciBpdGVyYXRvcjsKCiAgICBxaTo6cnVsZTwgaXRlcmF0b3IsIGNvbHVtbl9uYW1lX3QoKSA+IHF1b3RlZF9zdHJpbmcgPSAKICAgICAgICBxaTo6bGV4ZW1lWyJcIiIgPj4gK35xaTo6Y2hhcl8oIlwiIikgPj4gIlwiIl07CiAgICBxaTo6cnVsZTwgaXRlcmF0b3IsIGNvbHVtbl9hbmRfYWdncmVnYXRlKCksIHFpOjpzcGFjZV90eXBlID4gYWdnX3BhaXIgPQogICAgICAgIHF1b3RlZF9zdHJpbmcgIFsgcGh4OjphdF9jPDA+KHFpOjpfdmFsKSA9IHFpOjpfMSBdCiAgICAgICAgPiAnOicKICAgICAgICAvLyBBIHJ1bGUgdmFsaWRhdGlvbiB0ZWNobmljIGlzIHVzZWQgYmVsb3cuCiAgICAgICAgPiBxaTo6aW50X1txaTo6X3Bhc3MgPSAocWk6Ol8xID49QVZHICYmIHFpOjpfMTw9U1VNKSwgcGh4OjphdF9jPDE+KHFpOjpfdmFsKSA9IHFpOjpfMV07Ly86OmJvb3N0OjpiaW5kKCAmYXBwbHlfY29sX2FuZF9hZ2dyX3Zpc2l0b3IsIHFpOjpfdmFsLCBxaTo6XzEgKV07CiAgICBxaTo6cnVsZTwgaXRlcmF0b3IsIGNvbHVtbl9hbmRfYWdncmVnYXRlX2NvbnRhaW5lcigpLCBxaTo6c3BhY2VfdHlwZSA+IGFnZ3JlZ2F0ZXNfcGFyc2VyID0KICAgICAgICAneycKICAgICAgICA+IGFnZ19wYWlyLypbcGhvZW5peDo6cHVzaF9iYWNrKHFpOjpfdmFsLCBxaTo6XzEpXSovICUgJywnIC8vIE4uQi4hISEgbGlzdC1yZWR1eCB0ZWNobmljCiAgICAgICAgPiAnfSc7Cn0KCmJvb2wgZG9QYXJzZShjb25zdCBzdGQ6OnN0cmluZyYgaW5wdXQpCnsKICAgIHVzaW5nIG5hbWVzcGFjZSBwYXJzZXJzOwoKICAgIGF1dG8gZihiZWdpbihpbnB1dCkpLCBsKGVuZChpbnB1dCkpOwoKICAgIC8vcGFyc2VyPGl0ZXJhdG9yLCBxaTo6c3BhY2VfdHlwZT4gcDsKICAgIGNvbHVtbl9hbmRfYWdncmVnYXRlX2NvbnRhaW5lciBkYXRhOwogICAgdHJ5CiAgICB7CiAgICAgICAgYm9vbCBvayA9IHFpOjpwaHJhc2VfcGFyc2UoZixsLGFnZ3JlZ2F0ZXNfcGFyc2VyLHFpOjpzcGFjZSxkYXRhKTsKICAgICAgICBpZiAob2spICAgCiAgICAgICAgewogICAgICAgICAgICBzdGQ6OmNvdXQgPDwgInBhcnNlIHN1Y2Nlc3NcbiI7CiAgICAgICAgICAgIGZvciAoYXV0byYgcGFpciA6IGRhdGEpCiAgICAgICAgICAgICAgICBzdGQ6OmNvdXQgPDwgInJlc3VsdDogJyIgPDwgcGFpci5maXJzdCA8PCAiJyA6ICIgPDwgKGludCkgcGFpci5zZWNvbmQgPDwgIlxuIjsKICAgICAgICB9CiAgICAgICAgZWxzZSAgICAgIHN0ZDo6Y2VyciA8PCAicGFyc2UgZmFpbGVkOiAnIiA8PCBzdGQ6OnN0cmluZyhmLGwpIDw8ICInXG4iOwoKICAgICAgICBpZiAoZiE9bCkgc3RkOjpjZXJyIDw8ICJ0cmFpbGluZyB1bnBhcnNlZDogJyIgPDwgc3RkOjpzdHJpbmcoZixsKSA8PCAiJ1xuIjsKICAgICAgICByZXR1cm4gb2s7CiAgICB9CiAgICBjYXRjaChjb25zdCBxaTo6ZXhwZWN0YXRpb25fZmFpbHVyZTxpdGVyYXRvcj4mIGUpCiAgICB7CiAgICAgICAgc3RkOjpzdHJpbmcgZnJhZyhlLmZpcnN0LCBlLmxhc3QpOwogICAgICAgIHN0ZDo6Y2VyciA8PCBlLndoYXQoKSA8PCAiJyIgPDwgZnJhZyA8PCAiJ1xuIjsKICAgIH0KCiAgICByZXR1cm4gZmFsc2U7Cn0KCmludCBtYWluKCkKewogICAgLy9ib29sIG9rID0gZG9QYXJzZSgieyAnY29sdW1uIDEnIDogMSwgJ2NvbHVtbiAyJyA6IDAsICdjb2x1bW4gMycgOiAxIH0iKTsKICAgIGRvUGFyc2UoInsgXCJjb2x1bW4gMVwiIDogMSwgXCJjb2x1bW4gMlwiIDogMCwgXCJjb2x1bW4gM1wiIDogMSB9Iik7CiAgICAvL3JldHVybiBvaz8gMCA6IDI1NTsKfQo=