Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Boost Spirit placeholder type conversion

I'm trying to write a parser that (as a first step, of course it will be expanded a lot) parses a double and creates an object of my class ExpressionTree by passing that double to a factory method of my class. This was my first try

struct operands : qi::grammar<string::iterator, ExpressionTree()> 
{

    operands() : operands::base_type(start) 
    {
        start = qi::double_[qi::_val = ExpressionTree::number(qi::_1)];
    }

    qi::rule<string::iterator, ExpressionTree()> start;

};

This doesn't compile (can't convert from boost::spirit::_1_type to double) because (if I understand correctly) qi::_1 is not a double but only evaluates to a double.

I tried using boost::bind(&ExpressionTree::number, _1) in any way but I don't know how I then could get the result assigned to the attribute _val

I would be grateful if anyone could point me in the right direction.

like image 968
DanielAbele Avatar asked Oct 05 '22 03:10

DanielAbele


1 Answers

You need lazy actors in the semantic actions.

I'm assuming number is a static unary function or a non-static nullary (instead of, e.g. a type):

start = qi::double_ [ qi::_val = boost::phoenix::bind(&ExpressionTree::number, qi::_1)];

If it were a type:

start = qi::double_ [ qi::_val = boost::phoenix::construct<ExpressionTree::number>(qi::_1)];

See also

  • Semantic Actions
  • Adapting normal functions for Phoenix
  • Using polymorphic function objects as "lazy functions" in Phoenix
like image 119
sehe Avatar answered Oct 13 '22 10:10

sehe