Skip to content

Instantly share code, notes, and snippets.

@jefftrull
Created May 18, 2015 19:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jefftrull/b35e968504a8dc766dac to your computer and use it in GitHub Desktop.
Save jefftrull/b35e968504a8dc766dac to your computer and use it in GitHub Desktop.
Demonstration of apparent need for as_string when synthesizing a sequence of characters to a std::string
#include <string>
#include <iostream>
#include <sstream>
#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
int main() {
using namespace boost::spirit;
typedef istream_iterator iter_t;
// a rule that looks for any string that sandwiches another string
qi::rule<iter_t, locals<std::string>, qi::space_type> r;
// Works
r %= qi::as_string[lexeme[*(qi::char_ - ' ')]][qi::_a = _1] >> lexeme[*(qi::char_ - ' ')] >> ascii::string(qi::_a) ;
// Does not work
// r %= lexeme[*(qi::char_ - ' ')][qi::_a = _1] >> lexeme[*(qi::char_ - ' ')] >> ascii::string(qi::_a) ;
std::string test("FOO BAR FOO");
std::istringstream ss(test);
ss.unsetf(std::ios::skipws);
iter_t beg(ss), end;
if (!qi::phrase_parse(beg, end, r, qi::space)) {
std::cerr << "parse failed!\n";
return 1;
}
test = ("FOO BAR BAZ");
std::istringstream ss2(test);
ss2.unsetf(std::ios::skipws);
beg = iter_t(ss2);
if (qi::phrase_parse(beg, end, r, qi::space)) {
std::cerr << "parse succeeded, but should have failed!\n";
return 1;
}
return 0;
}
@jefftrull
Copy link
Author

Outcome: it's needed, but only because setting the local attribute in a semantic action as I do is just the same as performing an assignment, but lazy. Only attributes of an entire expression, being assigned into the rule's attribute type, get the special matching treatment that allows a sequence of characters to become either a string or a vector etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment