I am learning boost::spirit
, and I am trying to read and parse some text in a structure.
For example, "2: 4.6"
parsed as int 2
and double 4.6
in my TestStruct
below:
#include <iostream> #include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/support_istream_iterator.hpp> #include <boost/fusion/include/std_pair.hpp> namespace qi = boost::spirit::qi; struct TestStruct { int myint; double mydouble; TestStruct() {} TestStruct(std::pair<int,double> p) : myint(p.first), mydouble(p.second) {} }; template <typename Iterator, typename Skipper> struct MyGrammar : qi::grammar<Iterator, TestStruct(), Skipper> { MyGrammar() : MyGrammar::base_type(mystruct) { mystruct0 = qi::int_ >> ":" >> qi::double_; mystruct = mystruct0; } qi::rule<Iterator, std::pair<int,double>(), Skipper> mystruct0; qi::rule<Iterator, TestStruct(), Skipper> mystruct; }; int main() { typedef boost::spirit::istream_iterator It; std::cin.unsetf(std::ios::skipws); It it(std::cin), end; // input example: "2: 3.4" MyGrammar<It, qi::space_type> gr; TestStruct ts; if (qi::phrase_parse(it, end, gr, qi::space, ts) && it == end) std::cout << ts.myint << ", " << ts.mydouble << std::endl; return 0; }
This works well, but I wonder how this code can be simplified?
For example, I would like to get rid of the mystruct0
grammar mystruct0
, which exists only there, to mark the type std::pair<int,double>
, which is then used to automatically assemble the TestStruct
object from the mystruct
rule.
I would also like, if possible, to get rid of the TestStruct
constructor from std::pair
.
So, is it possible to somehow compile the following code? That would be much nicer:
struct TestStruct { int myint; double mydouble; TestStruct() {} TestStruct(int i, double d) : myint(i), mydouble(d) {} }; template <typename Iterator, typename Skipper> struct MyGrammar : qi::grammar<Iterator, TestStruct(), Skipper> { MyGrammar() : MyGrammar::base_type(mystruct) { mystruct = qi::int_ >> ":" >> qi::double_; } qi::rule<Iterator, TestStruct(), Skipper> mystruct; }; int main() { typedef boost::spirit::istream_iterator It; std::cin.unsetf(std::ios::skipws); It it(std::cin), end; // input example: "2: 3.4" MyGrammar<It, qi::space_type> gr; TestStruct ts; if (qi::phrase_parse(it, end, gr, qi::space, ts) && it == end) std::cout << ts.myint << ", " << ts.mydouble << std::endl; return 0; }
Unfortunately, the compiler says:
boost_1_49_0/include/boost/spirit/home/qi/detail/assign_to.hpp:123: error: no matching function for call to 'TestStruct::TestStruct(const int&)'