fork download
  1. #include <boost/fusion/adapted/std_pair.hpp>
  2. #include <boost/spirit/include/qi.hpp>
  3. #include <boost/spirit/include/phoenix.hpp>
  4. #include <boost/spirit/include/phoenix_fusion.hpp>
  5.  
  6. namespace qi = boost::spirit::qi;
  7. namespace phx = boost::phoenix;
  8.  
  9. typedef std::string column_name_t;
  10.  
  11. enum sql_faggregate
  12. {
  13. AVG,
  14. // ....
  15. SUM,
  16. };
  17.  
  18. typedef std::pair<column_name_t, int/*sql_faggregate*/> column_and_aggregate;
  19. typedef std::vector<column_and_aggregate> column_and_aggregate_container;
  20.  
  21. namespace parsers
  22. {
  23. typedef std::string::const_iterator iterator;
  24.  
  25. qi::rule< iterator, column_name_t() > quoted_string =
  26. qi::lexeme["\"" >> +~qi::char_("\"") >> "\""];
  27. qi::rule< iterator, column_and_aggregate(), qi::space_type > agg_pair =
  28. quoted_string [ phx::at_c<0>(qi::_val) = qi::_1 ]
  29. > ':'
  30. // A rule validation technic is used below.
  31. > 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 )];
  32. qi::rule< iterator, column_and_aggregate_container(), qi::space_type > aggregates_parser =
  33. '{'
  34. > agg_pair/*[phoenix::push_back(qi::_val, qi::_1)]*/ % ',' // N.B.!!! list-redux technic
  35. > '}';
  36. }
  37.  
  38. bool doParse(const std::string& input)
  39. {
  40. using namespace parsers;
  41.  
  42. auto f(begin(input)), l(end(input));
  43.  
  44. //parser<iterator, qi::space_type> p;
  45. column_and_aggregate_container data;
  46. try
  47. {
  48. bool ok = qi::phrase_parse(f,l,aggregates_parser,qi::space,data);
  49. if (ok)
  50. {
  51. std::cout << "parse success\n";
  52. for (auto& pair : data)
  53. std::cout << "result: '" << pair.first << "' : " << (int) pair.second << "\n";
  54. }
  55. else std::cerr << "parse failed: '" << std::string(f,l) << "'\n";
  56.  
  57. if (f!=l) std::cerr << "trailing unparsed: '" << std::string(f,l) << "'\n";
  58. return ok;
  59. }
  60. catch(const qi::expectation_failure<iterator>& e)
  61. {
  62. std::string frag(e.first, e.last);
  63. std::cerr << e.what() << "'" << frag << "'\n";
  64. }
  65.  
  66. return false;
  67. }
  68.  
  69. int main()
  70. {
  71. //bool ok = doParse("{ 'column 1' : 1, 'column 2' : 0, 'column 3' : 1 }");
  72. doParse("{ \"column 1\" : 1, \"column 2\" : 0, \"column 3\" : 1 }");
  73. //return ok? 0 : 255;
  74. }
  75.  
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty