28

This may be very obvious, but why does the stream-based parsing in boost duplicate the last letter? I must be doing something wrong:

#include <iostream>
#include <sstream>

#include <boost/spirit/include/qi.hpp>

namespace qi = boost::spirit::qi;

int main() {
    std::string input = "hello";
    std::stringstream ss(input);

    std::string r1, r2;
    boost::spirit::istream_iterator first(ss), last;

    qi::phrase_parse(input.begin(), input.end(), qi::lexeme[qi::alpha >> *qi::alnum], qi::space, r1);

    std::cout << r1 << std::endl; // prints "hello"

    qi::phrase_parse(first, last, qi::lexeme[qi::alpha >> *qi::alnum], qi::space, r2);

    std::cout << r2 << std::endl; // prints "helloo"
}

Tested with XCode 5.0 and Boost 1.54.0.

Edit: The problem seems to be specific to libc++. Anybody using Clang care to confirm?

kloffy
  • 2,928
  • 2
  • 25
  • 34
  • 2
    Your code prints two times "hello" on my system. Mingw, gcc 4.8.1, boost 1.54.0 – Mike M Oct 16 '13 at 10:45
  • Thank you for testing. I'll try a couple other configurations... – kloffy Oct 16 '13 at 11:18
  • 2
    Ok, it depends on whether I choose libc++ (incorrect output) or libstdc++ (correct output). This is strange... – kloffy Oct 16 '13 at 11:22
  • 2
    Very interesting. Excellent reproducer. Consider posting on the [spirit-general] list – sehe Oct 16 '13 at 16:15
  • There is no problem with Visual Studio 2013 RC, either. It must be specific to clang/libc++, or something is really wonky on my system. I have posted to the mailing list, hopefully somebody else can test it out... – kloffy Oct 17 '13 at 11:32
  • No problem either on my GNU/Linux box (debian) with g++ 4.7.2, boost 1.54, libstdc++ 4.9.1 – Carlo Wood Sep 10 '14 at 18:05

1 Answers1

1

If I understood correctly, you're not supposed to use input iterators, because they can give problems with backtracking. Maybe it's just sheer luck/a difference in implementation that this sometimes works at all.

ecotax
  • 1,933
  • 17
  • 22
  • 1
    Good point, but the example already uses a `boost::spirit::istream_iterator`, which according to my understanding should work. See here: http://boost-spirit.com/home/2010/01/05/stream-based-parsing-made-easy/. – kloffy Mar 19 '15 at 12:07
  • @kloffy: you're right, I completely overlooked the boost::spirit:: before it. – ecotax Mar 20 '15 at 09:52