[Spirit][Date_Time] Parsing of boost date_time (segfault)

Hi, I had a go at building a binary parser to output a date/time object. Unfortunately, I ran into some serious issues. One of my grammars causes the application to segfault when compiled with gcc, but not in clang. I'm not sure if this is a bug in gcc, boost, or simply a programming error. Please see attached file. Is there a better way to achieve what I need (final output should be ptime object)? All suggestions welcome :) Thanks, Vitaly

On 03/05/2011 2:55, Vitaly Budovski wrote:
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 = constructboost::gregorian::date(cref(year), cref(month), cref(day))] ) ;
You are passing references to local objects. Whenever the actual parsing happens, which it's not during grammar construction, the referred objects do not longer exist. You should declare those objects as class members, or even better use Phoenix's locals; and I'm pretty sure that there is a way to do what you want with no temporaries. The attribute of big_word[ref(year) = _1]>> byte_[ref(month) = _1]>> byte_[ref(day) = _1] should be something like tuple< uint16_t, uint8_t, uint8_t >, which one would be able to use to construct a gregorian date. I'm not fluent in Spirit, so I hope one of the experts out there comes up with an example on how to do this. Agustín Bergé.- http://talesofcpp.blogspot.com

On Tuesday, May 03, 2011 07:55:39 AM Vitaly Budovski wrote:
Hi,
I had a go at building a binary parser to output a date/time object. Unfortunately, I ran into some serious issues. One of my grammars causes the application to segfault when compiled with gcc, but not in clang. I'm not sure if this is a bug in gcc, boost, or simply a programming error. Please see attached file. Is there a better way to achieve what I need (final output should be ptime object)? All suggestions welcome :)
It's a programming error: The variables year, month, day, hour, minute and second are only defined in the constructor. You capture them by reference in the semantic actions. The actual parsing does not happen in the construct, thus those ctor local variables are invalid. One solution would be to use rule local variables, for example: qi::rule< Iterator , boost::gregorian::date() , qi::locals< uint16_t // year, refer to as _a , uint8_t // month, refer to as _b , uint8_t // day, refer to as c >
date;
date = (big_word[_a = _1] >> byte[_b = _1] >> byte[_c = _1]) [_val = constructboost::posix_time::time_duration(_a, _b, _c)] See attached file for a full working solution with locals.
Thanks,
Vitaly

date = (big_word[_a = _1] >> byte[_b = _1] >> byte[_c = _1]) [_val = constructboost::posix_time::time_duration(_a, _b, _c)]
See attached file for a full working solution with locals.
That makes sense. Thanks!
participants (3)
-
Agustín K-ballo Bergé
-
Thomas Heller
-
Vitaly Budovski