#include #include #include #include #include #include #include #include #include #include #include #include #include #include template struct test_generator: boost::spirit::karma::grammar { test_generator(): test_generator::base_type(start) { using boost::spirit::big_word; using boost::spirit::byte_; start = ( big_word(2007) << byte_(12) << byte_(31) << byte_(12) << byte_(30) << byte_(5) ) ; } boost::spirit::karma::rule start; }; template struct test_parser: boost::spirit::qi::grammar { test_parser(): test_parser::base_type(start) { using boost::spirit::big_word; using boost::spirit::byte_; using boost::spirit::omit; using boost::spirit::eps; using boost::spirit::_1; using boost::spirit::_2; using boost::spirit::_3; using boost::spirit::_val; using boost::phoenix::ref; using boost::phoenix::cref; using boost::phoenix::val; using boost::phoenix::construct; boost::uint16_t year; boost::uint8_t month; boost::uint8_t day; boost::uint8_t hour; boost::uint8_t minute; boost::uint8_t second; date = ( big_word[ref(year) = _1] >> byte_[ref(month) = _1] >> byte_[ref(day) = _1] >> eps[_val = construct(cref(year), cref(month), cref(day))] ) ; #if 1 // Segfault when enabled! (g++ 4.4.5, 4.5.2), works in clang 2.8 time = ( byte_[ref(hour) = _1] >> byte_[ref(minute) = _1] >> byte_[ref(second) = _1] >> eps[_val = construct(cref(hour), cref(minute), cref(second))] ) ; #endif start = ( date[std::cout << _1 << std::endl] >> time[std::cout << _1 << std::endl] ) ; } boost::spirit::qi::rule date; boost::spirit::qi::rule time; boost::spirit::qi::rule start; }; int main() { typedef boost::spirit::multi_pass< std::istreambuf_iterator > input_iterator_type; typedef std::ostream_iterator output_iterator_type; std::string filename("date_time.bin"); std::ofstream out(filename.c_str(), std::ios::binary | std::ios::trunc); if(!out) { std::cerr << "Failed to open output file\n"; return 1; } typedef test_generator test_generator; test_generator pg; output_iterator_type oi(out); bool result = boost::spirit::karma::generate(oi, pg); out.close(); std::ifstream in(filename.c_str(), std::ios::binary); if(!in) { std::cerr << "Failed to open input file\n"; return 1; } input_iterator_type first = input_iterator_type(in); input_iterator_type last = input_iterator_type(); typedef test_parser test_parser; test_parser pp; bool r = parse(first, last, pp); if(!r || first != last) { std::string rest(first, last); std::cerr << "Failed parsing at: 0x" << std::hex << (int)rest[0] << std::dec << std::endl; in.close(); return 1; } in.close(); return 0; }