Problem with semantic actions

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Problem with semantic actions

peterkochlarsen
Dear group,

I have studied spirit, and it is an amazing library, but not always
that easy to use.
One problem found is in the code below: I want to construct a height
structure in the semantic action,
but just can't find a way to make it work.
The error-message (MSVC2010) is:
d:\develop\playground\parsing\parse_height.cpp(158): error C2665:
'height::height' : none of the 3 overloads could convert all the
argument types
          d:\develop\playground\parsing\parse_height.cpp(127): could
be 'height::height(bool,int)'
          while trying to match the argument list '(bool, const
boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<T>,0>>)'
          with
          [
              T=boost::spirit::_1_type
          ]
The line in error is: (I removed some debug code/comments before
posting, so the line number differs in the attached code)

   lit('F')) >> int_   [_val = height(true,val(qi::_1))]

I have tried several variations but without any luck. What have I done wrong?

Best regards
Peter Koch Larsen

///////////// CODE
#include <string>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
using namespace boost::spirit;
using namespace boost::phoenix;
struct height
{
    bool    feet;
    int     val;
    height() = default;
    height(bool feet_,int val_):feet(feet_),val(val_) {}
};

template<class Iterator>
struct parse_height: qi::grammar<Iterator,height()>
{
    parse_height(): parse_height::base_type(start)
    {
        using namespace qi;
        start =
            (
                    (lit('F')) >> int_   [_val = height(true,val(qi::_1))]
                |   (lit('S')) >> int_   [_val = height(false,val(qi::_1))]
            );
    }
    qi::rule<Iterator, height()> start;
};

int main()
{
    using iter = std::string::const_iterator;
    using ph = parse_height<iter>;
    height h;
    ph parser;
    std::string::const_iterator iter = str.begin();
    std::string::const_iterator end = str.end();
    parse(iter, end, parser, h);
}

------------------------------------------------------------------------------
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: Problem with semantic actions

Lee Clagett-2
On Thu, Dec 10, 2015 at 5:33 AM, Peter Koch Larsen <[hidden email]> wrote:
Dear group,

I have studied spirit, and it is an amazing library, but not always
that easy to use.
One problem found is in the code below: I want to construct a height
structure in the semantic action,
but just can't find a way to make it work.
The error-message (MSVC2010) is:
d:\develop\playground\parsing\parse_height.cpp(158): error C2665:
'height::height' : none of the 3 overloads could convert all the
argument types
          d:\develop\playground\parsing\parse_height.cpp(127): could
be 'height::height(bool,int)'
          while trying to match the argument list '(bool, const
boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<T>,0>>)'
          with
          [
              T=boost::spirit::_1_type
          ]
The line in error is: (I removed some debug code/comments before
posting, so the line number differs in the attached code)

   lit('F')) >> int_   [_val = height(true,val(qi::_1))]

I have tried several variations but without any luck. What have I done wrong?

Best regards
Peter Koch Larsen

///////////// CODE
#include <string>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
using namespace boost::spirit;
using namespace boost::phoenix;
struct height
{
    bool    feet;
    int     val;
    height() = default;
    height(bool feet_,int val_):feet(feet_),val(val_) {}
};

template<class Iterator>
struct parse_height: qi::grammar<Iterator,height()>
{
    parse_height(): parse_height::base_type(start)
    {
        using namespace qi;
        start =
            (
                    (lit('F')) >> int_   [_val = height(true,val(qi::_1))]
                |   (lit('S')) >> int_   [_val = height(false,val(qi::_1))]
            );
    }
    qi::rule<Iterator, height()> start;
};

int main()
{
    using iter = std::string::const_iterator;
    using ph = parse_height<iter>;
    height h;
    ph parser;
    std::string::const_iterator iter = str.begin();
    std::string::const_iterator end = str.end();
    parse(iter, end, parser, h);
}


The semantic action must be a callable function. The expression `_val = ...` creates a callable if the right-hand-side is a phoenix actor, but `height(...)` is not a valid phoenix actor. Also, construction of the `height` object must be delayed because one of its constructor arguments is not immediately known. What you want is:

    int_ [_val = construct<height>(val(true), qi::_1)]

There are a few other bugs in the main function, but I think you can spot those.

Lee


------------------------------------------------------------------------------

_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: Problem with semantic actions

peterkochlarsen
Hi Lee,

Thank you. I need to learn boost::phoenix which I have more or less ignored so far.

/Peter