Suppose I have a std::string attribute, but for ease-of-parsing, I’d like to use qi::int_ or qi::double_.
Is there an easy way to do the conversion as a semantic action?
I tried something like this:
std::stringstream ss;
my_int_as_str = qi::int_ [ ref(ss)<<_1; _val=ss.str() ];
but this wouldn’t even compile.
EDIT – attempt with sehe’s answer below
#include <iostream>
#include <string>
#include <vector>
#include <boost/spirit/include/qi.hpp>
namespace qi=boost::spirit::qi;
namespace phx=boost::phoenix;
int main(int argc, char* argv[])
{
std::string test="123";
std::string result;
// 1. qi::raw[ qi::int_ ] works
// 2. qi::lexeme[ qi::int_ ] doesn't
// 3. qi::as_string[ qi::int_ ] doesn't
qi::rule<std::string::const_iterator, std::string()> my_int_as_str =
qi::raw[ qi::int_ ];
parse( test.cbegin(), test.cend(), my_int_as_str, result );
std::cout << result << std::endl;
// -------------------------------------------------------------------------
std::string test_vector="456 789";
std::vector<std::string> result_vector;
// 4. qi::raw[ qi::int_ ] won't compile
// 5. qi::lexeme[ qi::int_ ] won't compile
// 6. qi::as_string[ qi::int_ ] doesn't
qi::rule<std::string::const_iterator,std::vector<std::string>(),qi::space_type>
my_int_as_str_vector = qi::lexeme[ qi::int_ ];
phrase_parse(test_vector.cbegin(),test_vector.cend(),
my_int_as_str_vector,qi::space,result_vector);
for(auto& string: result_vector)
std::cout << string << std::endl;
return 0;
}
You can use
attr_castby specializingtransform_attributefor your types.If you really need/want to use semantic actions the simplest alternative would be to define a function taking an int as argument and returning a string (this is simpler than the
attr_castalternative but it is also slower, nearly twice the time in my really simple benchmarks):