lazy parser, the rules have inherited attributes, c++11

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

lazy parser, the rules have inherited attributes, c++11

MM
Where I choose the parser at parse time, by having a base pointer that set at parse time to point to the right rule to use, the call
 lazy(*_a)

from the nabialek trick example works when the rule pointed to by _a does not have any inherited attributes.

How does lazy(*_a) change then?

I have tried the 2nd part of the post here

without success.

What does lazy() expect?   An actor?



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

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

Re: lazy parser, the rules have inherited attributes, c++11

Joel de Guzman
On 7/25/15 5:38 AM, MM wrote:

> Where I choose the parser at parse time, by having a base pointer that set at parse time
> to point to the right rule to use, the call
>   lazy(*_a)
>
> from the nabialek trick example works when the rule pointed to by _a does not have any
> inherited attributes.
>
> How does lazy(*_a) change then?
>
> I have tried the 2nd part of the post here
> http://stackoverflow.com/questions/17717590/boost-spirit-qi-how-to-return-attributes-with-nabialek-trick
>
> without success.
>
> What does lazy() expect?   An actor?

lazy expects a function object. it has similar arguments as actions, so
you can get the _val and all the stuff just like actions. unlike actions
though, it is executed prior to parse.

Regards,
--
Joel de Guzman
http://www.ciere.com
http://boost-spirit.com
http://www.cycfi.com/


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

Re: lazy parser, the rules have inherited attributes, c++11

MM


On 25 July 2015 at 00:44, Joel de Guzman <[hidden email]> wrote:
On 7/25/15 5:38 AM, MM wrote:
> Where I choose the parser at parse time, by having a base pointer that set at parse time
> to point to the right rule to use, the call
>   lazy(*_a)
>
> from the nabialek trick example works when the rule pointed to by _a does not have any
> inherited attributes.
>
> How does lazy(*_a) change then?
>
> I have tried the 2nd part of the post here
> http://stackoverflow.com/questions/17717590/boost-spirit-qi-how-to-return-attributes-with-nabialek-trick
>
> without success.
>
> What does lazy() expect?   An actor?

lazy expects a function object. it has similar arguments as actions, so
you can get the _val and all the stuff just like actions. unlike actions
though, it is executed prior to parse.

Regards,
--
Joel de Guzman

Thanks,

but if in the above
  ... >>  lazy(*_a)  ;
_a pointer to a rule with no inherited attributes, it works.

but if _a points to a rule with 1 attribute (for e.g _r1), how do you call that?

  ... >>  lazy(*_a) (_r1)

or

  ... >> lazy( (*_a) (_r1) )

or use a phoenix function ?

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

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

Re: lazy parser, the rules have inherited attributes, c++11

Joel de Guzman
On 7/25/15 8:30 AM, MM wrote:

>
>
> On 25 July 2015 at 00:44, Joel de Guzman <[hidden email] <mailto:[hidden email]>> wrote:
>
>     On 7/25/15 5:38 AM, MM wrote:
>     > Where I choose the parser at parse time, by having a base pointer that set at parse time
>     > to point to the right rule to use, the call
>     >   lazy(*_a)
>     >
>     > from the nabialek trick example works when the rule pointed to by _a does not have any
>     > inherited attributes.
>     >
>     > How does lazy(*_a) change then?
>     >
>     > I have tried the 2nd part of the post here
>     >http://stackoverflow.com/questions/17717590/boost-spirit-qi-how-to-return-attributes-with-nabialek-trick
>     >
>     > without success.
>     >
>     > What does lazy() expect?   An actor?
>
>     lazy expects a function object. it has similar arguments as actions, so
>     you can get the _val and all the stuff just like actions. unlike actions
>     though, it is executed prior to parse.
>
>     Regards,
>     --
>     Joel de Guzman
>
> Thanks,
>
> but if in the above
>    ... >>  lazy(*_a)  ;
> _a pointer to a rule with no inherited attributes, it works.
>
> but if _a points to a rule with 1 attribute (for e.g _r1), how do you call that?
>
>    ... >>  lazy(*_a) (_r1)
>
> or
>
>    ... >> lazy( (*_a) (_r1) )
>
> or use a phoenix function ?

I think it should be the latter. Keep in mind though that _r1 in this case
is the inherited attribute of the rule at the call site (not the *_a). If
the inherited attribute is an int, for example, you can write:

    lazy( (*_a)(1234) )

Regards,
--
Joel de Guzman
http://www.ciere.com
http://boost-spirit.com
http://www.cycfi.com/


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

Re: lazy parser, the rules have inherited attributes, c++11

MM


On 25 July 2015 at 05:40, Joel de Guzman <[hidden email]> wrote:
On 7/25/15 8:30 AM, MM wrote:
>
>
> On 25 July 2015 at 00:44, Joel de Guzman <[hidden email] <mailto:[hidden email]>> wrote:
>
>     On 7/25/15 5:38 AM, MM wrote:
>     > Where I choose the parser at parse time, by having a base pointer that set at parse time
>     > to point to the right rule to use, the call
>     >   lazy(*_a)
>     >
>     > from the nabialek trick example works when the rule pointed to by _a does not have any
>     > inherited attributes.
>     >
>     > How does lazy(*_a) change then?
>     >
>     > I have tried the 2nd part of the post here
>     >http://stackoverflow.com/questions/17717590/boost-spirit-qi-how-to-return-attributes-with-nabialek-trick
>     >
>     > without success.
>     >
>     > What does lazy() expect?   An actor?
>
>     lazy expects a function object. it has similar arguments as actions, so
>     you can get the _val and all the stuff just like actions. unlike actions
>     though, it is executed prior to parse.
>
>     Regards,
>     --
>     Joel de Guzman
>
> Thanks,
>
> but if in the above
>    ... >>  lazy(*_a)  ;
> _a pointer to a rule with no inherited attributes, it works.
>
> but if _a points to a rule with 1 attribute (for e.g _r1), how do you call that?
>
>    ... >>  lazy(*_a) (_r1)
>
> or
>
>    ... >> lazy( (*_a) (_r1) )
>
> or use a phoenix function ?

I think it should be the latter. Keep in mind though that _r1 in this case
is the inherited attribute of the rule at the call site (not the *_a). If
the inherited attribute is an int, for example, you can write:

    lazy( (*_a)(1234) )


I haven't made progress  here, so I am restarting from scratch:
The following fails to compile with g++ 5.1.1 boost 1.57. My grammar is wrong somewhere but I don't know where. The compile error refers to the "reference" header files so I guess it's the &r1 bit that doesn't work... Once the following is sorted, I will have a followup question.

#include <boost/spirit/include/support_utree.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/assert.hpp>
#include <iostream>
#include <string>
#include <cstdlib>

template <typename P, typename T>
void test_phrase_parser_attr(
    char const* input, P const& p, T& attr, bool full_match = true)
{
    using boost::spirit::qi::phrase_parse;
    using boost::spirit::qi::ascii::blank;

    char const* f(input);
    char const* l(f + strlen(f));
    if (phrase_parse(f, l, p, blank, attr) && (!full_match || (f == l)))
        std::cout << "ok" << std::endl;
    else
        std::cout << "fail" << std::endl;
}

int main()
{
  namespace qis = boost::spirit::qi;
  using qis::lazy; using qis::_val; using qis::lit;
  using qis::_a;
  using boost::phoenix::val;

  using Rule =
    qis::rule<std::string::const_iterator, std::string(), qis::blank_type>;
  
  Rule r1 = lit("X1") [ _val = "X1" ];
  Rule r2 = lit("X2") [ _val = "X2" ];
  Rule* rptr;

  qis::rule<std::string::const_iterator, std::string(),
    qis::locals<Rule*>,  qis::blank_type> dispatcher;
  dispatcher  %=
    ( qis::lit("Test1") [ _a = &r1 ] | qis::lit("Test2") [ _a = &r2 ]) >>
    lazy(*_a);

  std::string attr;
  test_phrase_parser_attr("Test1 X1", dispatcher, attr );
  return 0;
}

regards,
MM


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

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

Re: lazy parser, the rules have inherited attributes, c++11

TONGARI J
2015-08-10 3:12 GMT+08:00 MM <[hidden email]>:


On 25 July 2015 at 05:40, Joel de Guzman <[hidden email]> wrote:
On 7/25/15 8:30 AM, MM wrote:
>
>
> On 25 July 2015 at 00:44, Joel de Guzman <[hidden email] <mailto:[hidden email]>> wrote:
>
>     On 7/25/15 5:38 AM, MM wrote:
>     > Where I choose the parser at parse time, by having a base pointer that set at parse time
>     > to point to the right rule to use, the call
>     >   lazy(*_a)
>     >
>     > from the nabialek trick example works when the rule pointed to by _a does not have any
>     > inherited attributes.
>     >
>     > How does lazy(*_a) change then?
>     >
>     > I have tried the 2nd part of the post here
>     >http://stackoverflow.com/questions/17717590/boost-spirit-qi-how-to-return-attributes-with-nabialek-trick
>     >
>     > without success.
>     >
>     > What does lazy() expect?   An actor?
>
>     lazy expects a function object. it has similar arguments as actions, so
>     you can get the _val and all the stuff just like actions. unlike actions
>     though, it is executed prior to parse.
>
>     Regards,
>     --
>     Joel de Guzman
>
> Thanks,
>
> but if in the above
>    ... >>  lazy(*_a)  ;
> _a pointer to a rule with no inherited attributes, it works.
>
> but if _a points to a rule with 1 attribute (for e.g _r1), how do you call that?
>
>    ... >>  lazy(*_a) (_r1)
>
> or
>
>    ... >> lazy( (*_a) (_r1) )
>
> or use a phoenix function ?

I think it should be the latter. Keep in mind though that _r1 in this case
is the inherited attribute of the rule at the call site (not the *_a). If
the inherited attribute is an int, for example, you can write:

    lazy( (*_a)(1234) )


I haven't made progress  here, so I am restarting from scratch:
The following fails to compile with g++ 5.1.1 boost 1.57. My grammar is wrong somewhere but I don't know where. The compile error refers to the "reference" header files so I guess it's the &r1 bit that doesn't work... Once the following is sorted, I will have a followup question.

#include <boost/spirit/include/support_utree.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/assert.hpp>
#include <iostream>
#include <string>
#include <cstdlib>

template <typename P, typename T>
void test_phrase_parser_attr(
    char const* input, P const& p, T& attr, bool full_match = true)
{
    using boost::spirit::qi::phrase_parse;
    using boost::spirit::qi::ascii::blank;

    char const* f(input);
    char const* l(f + strlen(f));
    if (phrase_parse(f, l, p, blank, attr) && (!full_match || (f == l)))
        std::cout << "ok" << std::endl;
    else
        std::cout << "fail" << std::endl;
}

int main()
{
  namespace qis = boost::spirit::qi;
  using qis::lazy; using qis::_val; using qis::lit;
  using qis::_a;
  using boost::phoenix::val;

  using Rule =
    qis::rule<std::string::const_iterator, std::string(), qis::blank_type>;
  
  Rule r1 = lit("X1") [ _val = "X1" ];
  Rule r2 = lit("X2") [ _val = "X2" ];
  Rule* rptr;

  qis::rule<std::string::const_iterator, std::string(),
    qis::locals<Rule*>,  qis::blank_type> dispatcher;
  dispatcher  %=
    ( qis::lit("Test1") [ _a = &r1 ] | qis::lit("Test2") [ _a = &r2 ]) >>
    lazy(*_a);

  std::string attr;
  test_phrase_parser_attr("Test1 X1", dispatcher, attr );
  return 0;
}

I didn't compile your code. By skimming over it, I think you need addressof instead of & for rules at least.

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

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

Re: lazy parser, the rules have inherited attributes, c++11

MM
On 10 August 2015 at 02:11, TONGARI J <[hidden email]> wrote:
2015-08-10 3:12 GMT+08:00 MM <[hidden email]>:


On 25 July 2015 at 05:40, Joel de Guzman <[hidden email]> wrote:
On 7/25/15 8:30 AM, MM wrote:
>
>
> On 25 July 2015 at 00:44, Joel de Guzman <[hidden email] <mailto:[hidden email]>> wrote:
>
>     On 7/25/15 5:38 AM, MM wrote:
>     > Where I choose the parser at parse time, by having a base pointer that set at parse time
>     > to point to the right rule to use, the call
>     >   lazy(*_a)
>     >
>     > from the nabialek trick example works when the rule pointed to by _a does not have any
>     > inherited attributes.
>     >
>     > How does lazy(*_a) change then?
>     >
>     > I have tried the 2nd part of the post here
>     >http://stackoverflow.com/questions/17717590/boost-spirit-qi-how-to-return-attributes-with-nabialek-trick
>     >
>     > without success.
>     >
>     > What does lazy() expect?   An actor?
>
>     lazy expects a function object. it has similar arguments as actions, so
>     you can get the _val and all the stuff just like actions. unlike actions
>     though, it is executed prior to parse.
>
>     Regards,
>     --
>     Joel de Guzman
>
> Thanks,
>
> but if in the above
>    ... >>  lazy(*_a)  ;
> _a pointer to a rule with no inherited attributes, it works.
>
> but if _a points to a rule with 1 attribute (for e.g _r1), how do you call that?
>
>    ... >>  lazy(*_a) (_r1)
>
> or
>
>    ... >> lazy( (*_a) (_r1) )
>
> or use a phoenix function ?

I think it should be the latter. Keep in mind though that _r1 in this case
is the inherited attribute of the rule at the call site (not the *_a). If
the inherited attribute is an int, for example, you can write:

    lazy( (*_a)(1234) )


I haven't made progress  here, so I am restarting from scratch:
The following fails to compile with g++ 5.1.1 boost 1.57. My grammar is wrong somewhere but I don't know where. The compile error refers to the "reference" header files so I guess it's the &r1 bit that doesn't work... Once the following is sorted, I will have a followup question.

#include <boost/spirit/include/support_utree.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/assert.hpp>
#include <iostream>
#include <string>
#include <cstdlib>

template <typename P, typename T>
void test_phrase_parser_attr(
    char const* input, P const& p, T& attr, bool full_match = true)
{
    using boost::spirit::qi::phrase_parse;
    using boost::spirit::qi::ascii::blank;

    char const* f(input);
    char const* l(f + strlen(f));
    if (phrase_parse(f, l, p, blank, attr) && (!full_match || (f == l)))
        std::cout << "ok" << std::endl;
    else
        std::cout << "fail" << std::endl;
}

int main()
{
  namespace qis = boost::spirit::qi;
  using qis::lazy; using qis::_val; using qis::lit;
  using qis::_a;
  using boost::phoenix::val;

  using Rule =
    qis::rule<std::string::const_iterator, std::string(), qis::blank_type>;
  
  Rule r1 = lit("X1") [ _val = "X1" ];
  Rule r2 = lit("X2") [ _val = "X2" ];
  Rule* rptr;

  qis::rule<std::string::const_iterator, std::string(),
    qis::locals<Rule*>,  qis::blank_type> dispatcher;
  dispatcher  %=
    ( qis::lit("Test1") [ _a = &r1 ] | qis::lit("Test2") [ _a = &r2 ]) >>
    lazy(*_a);

  std::string attr;
  test_phrase_parser_attr("Test1 X1", dispatcher, attr );
  return 0;
}

I didn't compile your code. By skimming over it, I think you need addressof instead of & for rules at least.

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

Sorry, what is this addressof... I couldn't find it in the spirit QI index. Btw, this is not x3.

Rds,

MM

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

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

Re: lazy parser, the rules have inherited attributes, c++11

Lee Clagett-2


On Mon, Aug 10, 2015 at 2:36 PM, MM <[hidden email]> wrote:
On 10 August 2015 at 02:11, TONGARI J <[hidden email]> wrote:
2015-08-10 3:12 GMT+08:00 MM <[hidden email]>:


On 25 July 2015 at 05:40, Joel de Guzman <[hidden email]> wrote:
On 7/25/15 8:30 AM, MM wrote:
>
>
> On 25 July 2015 at 00:44, Joel de Guzman <[hidden email] <mailto:[hidden email]>> wrote:
>
>     On 7/25/15 5:38 AM, MM wrote:
>     > Where I choose the parser at parse time, by having a base pointer that set at parse time
>     > to point to the right rule to use, the call
>     >   lazy(*_a)
>     >
>     > from the nabialek trick example works when the rule pointed to by _a does not have any
>     > inherited attributes.
>     >
>     > How does lazy(*_a) change then?
>     >
>     > I have tried the 2nd part of the post here
>     >http://stackoverflow.com/questions/17717590/boost-spirit-qi-how-to-return-attributes-with-nabialek-trick
>     >
>     > without success.
>     >
>     > What does lazy() expect?   An actor?
>
>     lazy expects a function object. it has similar arguments as actions, so
>     you can get the _val and all the stuff just like actions. unlike actions
>     though, it is executed prior to parse.
>
>     Regards,
>     --
>     Joel de Guzman
>
> Thanks,
>
> but if in the above
>    ... >>  lazy(*_a)  ;
> _a pointer to a rule with no inherited attributes, it works.
>
> but if _a points to a rule with 1 attribute (for e.g _r1), how do you call that?
>
>    ... >>  lazy(*_a) (_r1)
>
> or
>
>    ... >> lazy( (*_a) (_r1) )
>
> or use a phoenix function ?

I think it should be the latter. Keep in mind though that _r1 in this case
is the inherited attribute of the rule at the call site (not the *_a). If
the inherited attribute is an int, for example, you can write:

    lazy( (*_a)(1234) )


I haven't made progress  here, so I am restarting from scratch:
The following fails to compile with g++ 5.1.1 boost 1.57. My grammar is wrong somewhere but I don't know where. The compile error refers to the "reference" header files so I guess it's the &r1 bit that doesn't work... Once the following is sorted, I will have a followup question.

#include <boost/spirit/include/support_utree.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/assert.hpp>
#include <iostream>
#include <string>
#include <cstdlib>

template <typename P, typename T>
void test_phrase_parser_attr(
    char const* input, P const& p, T& attr, bool full_match = true)
{
    using boost::spirit::qi::phrase_parse;
    using boost::spirit::qi::ascii::blank;

    char const* f(input);
    char const* l(f + strlen(f));
    if (phrase_parse(f, l, p, blank, attr) && (!full_match || (f == l)))
        std::cout << "ok" << std::endl;
    else
        std::cout << "fail" << std::endl;
}

int main()
{
  namespace qis = boost::spirit::qi;
  using qis::lazy; using qis::_val; using qis::lit;
  using qis::_a;
  using boost::phoenix::val;

  using Rule =
    qis::rule<std::string::const_iterator, std::string(), qis::blank_type>;
  
  Rule r1 = lit("X1") [ _val = "X1" ];
  Rule r2 = lit("X2") [ _val = "X2" ];
  Rule* rptr;

  qis::rule<std::string::const_iterator, std::string(),
    qis::locals<Rule*>,  qis::blank_type> dispatcher;
  dispatcher  %=
    ( qis::lit("Test1") [ _a = &r1 ] | qis::lit("Test2") [ _a = &r2 ]) >>
    lazy(*_a);

  std::string attr;
  test_phrase_parser_attr("Test1 X1", dispatcher, attr );
  return 0;
}

I didn't compile your code. By skimming over it, I think you need addressof instead of & for rules at least.

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

Sorry, what is this addressof... I couldn't find it in the spirit QI index. Btw, this is not x3.

Rds,

MM

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

_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general


From cppreference[1]:

Obtains the actual address of the object or function arg, even in presence of overloaded operator&

Boost [2] also has a version if you are using a c++11 only compiler.

[1] http://en.cppreference.com/w/cpp/memory/addressof
[2] http://www.boost.org/doc/libs/1_58_0/libs/core/doc/html/core/addressof.html

Lee


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

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

Re: lazy parser, the rules have inherited attributes, c++11

MM


On 10 August 2015 at 20:33, Lee Clagett <[hidden email]> wrote:


On Mon, Aug 10, 2015 at 2:36 PM, MM <[hidden email]> wrote:
On 10 August 2015 at 02:11, TONGARI J <[hidden email]> wrote:
2015-08-10 3:12 GMT+08:00 MM <[hidden email]>:


On 25 July 2015 at 05:40, Joel de Guzman <[hidden email]> wrote:
On 7/25/15 8:30 AM, MM wrote:
>
>
> On 25 July 2015 at 00:44, Joel de Guzman <[hidden email] <mailto:[hidden email]>> wrote:
>
>     On 7/25/15 5:38 AM, MM wrote:
>     > Where I choose the parser at parse time, by having a base pointer that set at parse time
>     > to point to the right rule to use, the call
>     >   lazy(*_a)
>     >
>     > from the nabialek trick example works when the rule pointed to by _a does not have any
>     > inherited attributes.
>     >
>     > How does lazy(*_a) change then?
>     >
>     > I have tried the 2nd part of the post here
>     >http://stackoverflow.com/questions/17717590/boost-spirit-qi-how-to-return-attributes-with-nabialek-trick
>     >
>     > without success.
>     >
>     > What does lazy() expect?   An actor?
>
>     lazy expects a function object. it has similar arguments as actions, so
>     you can get the _val and all the stuff just like actions. unlike actions
>     though, it is executed prior to parse.
>
>     Regards,
>     --
>     Joel de Guzman
>
> Thanks,
>
> but if in the above
>    ... >>  lazy(*_a)  ;
> _a pointer to a rule with no inherited attributes, it works.
>
> but if _a points to a rule with 1 attribute (for e.g _r1), how do you call that?
>
>    ... >>  lazy(*_a) (_r1)
>
> or
>
>    ... >> lazy( (*_a) (_r1) )
>
> or use a phoenix function ?

I think it should be the latter. Keep in mind though that _r1 in this case
is the inherited attribute of the rule at the call site (not the *_a). If
the inherited attribute is an int, for example, you can write:

    lazy( (*_a)(1234) )


I haven't made progress  here, so I am restarting from scratch:
The following fails to compile with g++ 5.1.1 boost 1.57. My grammar is wrong somewhere but I don't know where. The compile error refers to the "reference" header files so I guess it's the &r1 bit that doesn't work... Once the following is sorted, I will have a followup question.

#include <boost/spirit/include/support_utree.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/assert.hpp>
#include <iostream>
#include <string>
#include <cstdlib>

template <typename P, typename T>
void test_phrase_parser_attr(
    char const* input, P const& p, T& attr, bool full_match = true)
{
    using boost::spirit::qi::phrase_parse;
    using boost::spirit::qi::ascii::blank;

    char const* f(input);
    char const* l(f + strlen(f));
    if (phrase_parse(f, l, p, blank, attr) && (!full_match || (f == l)))
        std::cout << "ok" << std::endl;
    else
        std::cout << "fail" << std::endl;
}

int main()
{
  namespace qis = boost::spirit::qi;
  using qis::lazy; using qis::_val; using qis::lit;
  using qis::_a;
  using boost::phoenix::val;

  using Rule =
    qis::rule<std::string::const_iterator, std::string(), qis::blank_type>;
  
  Rule r1 = lit("X1") [ _val = "X1" ];
  Rule r2 = lit("X2") [ _val = "X2" ];
  Rule* rptr;

  qis::rule<std::string::const_iterator, std::string(),
    qis::locals<Rule*>,  qis::blank_type> dispatcher;
  dispatcher  %=
    ( qis::lit("Test1") [ _a = &r1 ] | qis::lit("Test2") [ _a = &r2 ]) >>
    lazy(*_a);

  std::string attr;
  test_phrase_parser_attr("Test1 X1", dispatcher, attr );
  return 0;
}

I didn't compile your code. By skimming over it, I think you need addressof instead of & for rules at least.

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

Sorry, what is this addressof... I couldn't find it in the spirit QI index. Btw, this is not x3.

Rds,

MM

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


From cppreference[1]:

Obtains the actual address of the object or function arg, even in presence of overloaded operator&

Boost [2] also has a version if you are using a c++11 only compiler.

[1] http://en.cppreference.com/w/cpp/memory/addressof
[2] http://www.boost.org/doc/libs/1_58_0/libs/core/doc/html/core/addressof.html

Lee

Fantastic, that was the problem. Below is the code that compiles and runs (I corrected the rule's iterator and the blank type as well):

#include <boost/spirit/include/support_utree.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/assert.hpp>
#include <iostream>
#include <string>
#include <cstdlib>

template <typename P, typename T>
void test_phrase_parser_attr(
    char const* input, P const& p, T& attr, bool full_match = true)
{
    using boost::spirit::qi::phrase_parse;
    using boost::spirit::qi::standard::blank;

    char const* f(input);
    char const* l(f + strlen(f));
    if (phrase_parse(f, l, p, blank, attr) && (!full_match || (f == l)))
        std::cout << "ok" << std::endl;
    else
        std::cout << "fail" << std::endl;
}

int main()
{
  namespace qis = boost::spirit::qi;
  using qis::lazy; using qis::_val; using qis::lit;
  using qis::_a;
  using boost::phoenix::val;

  using Rule =
    qis::rule<const char*, std::string(), qis::blank_type>;
  
  Rule r1 = lit("X1") [ _val = "X1" ];
  Rule r2 = lit("X2") [ _val = "X2" ];
  Rule* rptr;

  qis::rule<const char*, std::string(), qis::locals<Rule*>,  qis::blank_type>
    dispatcher;
  dispatcher  %=
    ( qis::lit("Test1") [ _a = std::addressof(r1) ] | qis::lit("Test2") [ _a = std::addressof(r2) ]) >>
    lazy(*_a);

  std::string attr;
  test_phrase_parser_attr("Test2 X2", dispatcher, attr );
  std::cout<< "value="<< attr <<std::endl;
 
  return 0;
}

Now, how can I make r1 and r2 take an inherited attribute of type int, and lazily pass the int ?
Let's say I add a local variable _b of type int, which I populate with either 1 or 2 depending on whether I parsed Test1 or Test2, and pass that 1 or 2 to whatever rule is pointed to by _a ?

Thanks

MM

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

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

Re: lazy parser, the rules have inherited attributes, c++11

MM


On 10 August 2015 at 21:08, MM <[hidden email]> wrote:


On 10 August 2015 at 20:33, Lee Clagett <[hidden email]> wrote:


On Mon, Aug 10, 2015 at 2:36 PM, MM <[hidden email]> wrote:
On 10 August 2015 at 02:11, TONGARI J <[hidden email]> wrote:
2015-08-10 3:12 GMT+08:00 MM <[hidden email]>:


On 25 July 2015 at 05:40, Joel de Guzman <[hidden email]> wrote:
On 7/25/15 8:30 AM, MM wrote:
>
>
> On 25 July 2015 at 00:44, Joel de Guzman <[hidden email] <mailto:[hidden email]>> wrote:
>
>     On 7/25/15 5:38 AM, MM wrote:
>     > Where I choose the parser at parse time, by having a base pointer that set at parse time
>     > to point to the right rule to use, the call
>     >   lazy(*_a)
>     >
>     > from the nabialek trick example works when the rule pointed to by _a does not have any
>     > inherited attributes.
>     >
>     > How does lazy(*_a) change then?
>     >
>     > I have tried the 2nd part of the post here
>     >http://stackoverflow.com/questions/17717590/boost-spirit-qi-how-to-return-attributes-with-nabialek-trick
>     >
>     > without success.
>     >
>     > What does lazy() expect?   An actor?
>
>     lazy expects a function object. it has similar arguments as actions, so
>     you can get the _val and all the stuff just like actions. unlike actions
>     though, it is executed prior to parse.
>
>     Regards,
>     --
>     Joel de Guzman
>
> Thanks,
>
> but if in the above
>    ... >>  lazy(*_a)  ;
> _a pointer to a rule with no inherited attributes, it works.
>
> but if _a points to a rule with 1 attribute (for e.g _r1), how do you call that?
>
>    ... >>  lazy(*_a) (_r1)
>
> or
>
>    ... >> lazy( (*_a) (_r1) )
>
> or use a phoenix function ?

I think it should be the latter. Keep in mind though that _r1 in this case
is the inherited attribute of the rule at the call site (not the *_a). If
the inherited attribute is an int, for example, you can write:

    lazy( (*_a)(1234) )


I haven't made progress  here, so I am restarting from scratch:
The following fails to compile with g++ 5.1.1 boost 1.57. My grammar is wrong somewhere but I don't know where. The compile error refers to the "reference" header files so I guess it's the &r1 bit that doesn't work... Once the following is sorted, I will have a followup question.

#include <boost/spirit/include/support_utree.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/assert.hpp>
#include <iostream>
#include <string>
#include <cstdlib>

template <typename P, typename T>
void test_phrase_parser_attr(
    char const* input, P const& p, T& attr, bool full_match = true)
{
    using boost::spirit::qi::phrase_parse;
    using boost::spirit::qi::ascii::blank;

    char const* f(input);
    char const* l(f + strlen(f));
    if (phrase_parse(f, l, p, blank, attr) && (!full_match || (f == l)))
        std::cout << "ok" << std::endl;
    else
        std::cout << "fail" << std::endl;
}

int main()
{
  namespace qis = boost::spirit::qi;
  using qis::lazy; using qis::_val; using qis::lit;
  using qis::_a;
  using boost::phoenix::val;

  using Rule =
    qis::rule<std::string::const_iterator, std::string(), qis::blank_type>;
  
  Rule r1 = lit("X1") [ _val = "X1" ];
  Rule r2 = lit("X2") [ _val = "X2" ];
  Rule* rptr;

  qis::rule<std::string::const_iterator, std::string(),
    qis::locals<Rule*>,  qis::blank_type> dispatcher;
  dispatcher  %=
    ( qis::lit("Test1") [ _a = &r1 ] | qis::lit("Test2") [ _a = &r2 ]) >>
    lazy(*_a);

  std::string attr;
  test_phrase_parser_attr("Test1 X1", dispatcher, attr );
  return 0;
}

I didn't compile your code. By skimming over it, I think you need addressof instead of & for rules at least.

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

Sorry, what is this addressof... I couldn't find it in the spirit QI index. Btw, this is not x3.

Rds,

MM

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


From cppreference[1]:

Obtains the actual address of the object or function arg, even in presence of overloaded operator&

Boost [2] also has a version if you are using a c++11 only compiler.

[1] http://en.cppreference.com/w/cpp/memory/addressof
[2] http://www.boost.org/doc/libs/1_58_0/libs/core/doc/html/core/addressof.html

Lee

Fantastic, that was the problem. Below is the code that compiles and runs (I corrected the rule's iterator and the blank type as well):

#include <boost/spirit/include/support_utree.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/assert.hpp>
#include <iostream>
#include <string>
#include <cstdlib>

template <typename P, typename T>
void test_phrase_parser_attr(
    char const* input, P const& p, T& attr, bool full_match = true)
{
    using boost::spirit::qi::phrase_parse;
    using boost::spirit::qi::standard::blank;

    char const* f(input);
    char const* l(f + strlen(f));
    if (phrase_parse(f, l, p, blank, attr) && (!full_match || (f == l)))
        std::cout << "ok" << std::endl;
    else
        std::cout << "fail" << std::endl;
}

int main()
{
  namespace qis = boost::spirit::qi;
  using qis::lazy; using qis::_val; using qis::lit;
  using qis::_a;
  using boost::phoenix::val;

  using Rule =
    qis::rule<const char*, std::string(), qis::blank_type>;
  
  Rule r1 = lit("X1") [ _val = "X1" ];
  Rule r2 = lit("X2") [ _val = "X2" ];
  Rule* rptr;

  qis::rule<const char*, std::string(), qis::locals<Rule*>,  qis::blank_type>
    dispatcher;
  dispatcher  %=
    ( qis::lit("Test1") [ _a = std::addressof(r1) ] | qis::lit("Test2") [ _a = std::addressof(r2) ]) >>
    lazy(*_a);

  std::string attr;
  test_phrase_parser_attr("Test2 X2", dispatcher, attr );
  std::cout<< "value="<< attr <<std::endl;
 
  return 0;
}

Now, how can I make r1 and r2 take an inherited attribute of type int, and lazily pass the int ?
Let's say I add a local variable _b of type int, which I populate with either 1 or 2 depending on whether I parsed Test1 or Test2, and pass that 1 or 2 to whatever rule is pointed to by _a ?

Thanks

MM
I have tried by 
1. changing the rules' signatures to be std::string(int)
2. added a local of type int, and assigned 1 or 2 to it  (to _b)
3. then lazily called it. None of  lazy(*_a(_b))         lazy((*_a)(b))     lazy(*_a)(b)    compiled.

Thanks

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

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

Re: lazy parser, the rules have inherited attributes, c++11

TONGARI J
2015-08-11 21:48 GMT+08:00 MM <[hidden email]>:
I have tried by 
1. changing the rules' signatures to be std::string(int)
2. added a local of type int, and assigned 1 or 2 to it  (to _b)
3. then lazily called it. None of  lazy(*_a(_b))         lazy((*_a)(b))     lazy(*_a)(b)    compiled.

Well, it's simply impossible in V2, see

You may consider using kwd directive if possible:

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

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

Re: lazy parser, the rules have inherited attributes, c++11

MM

On 11 August 2015 at 15:32, TONGARI J <[hidden email]> wrote:
2015-08-11 21:48 GMT+08:00 MM <[hidden email]>:
I have tried by 
1. changing the rules' signatures to be std::string(int)
2. added a local of type int, and assigned 1 or 2 to it  (to _b)
3. then lazily called it. None of  lazy(*_a(_b))         lazy((*_a)(b))     lazy(*_a)(b)    compiled.

Well, it's simply impossible in V2, see

You may consider using kwd directive if possible:

Perhaps, I am not sure. Here is what I am trying to do. I am trying to parse a line like this:

field1=value1 field2=value2 type=CF field3=value3 xtra1=100000.0 xtra2=2015-08-10

the field 'type' can have x different values ( 'CF', 'F', 'DFB' .... )
Depending on which value it is, I instantiate an object of type Derived1, or Derived2, or Derived3 that all have a common Base.
Once I obtain the Base*, I would like to pass it on to a appropriate parser for the xtras fields.
The xtras for Derived1 are different frmo the xtras for Derived2 and so on.

What I was doing is to parse first the part:
  field1=value1 field2=value2 type=CF field3=value3
which has always the same format. I construct the appropriate object. I select the appropriate rule pointer, then I lazily call that pointed rule. And I would have liked to pass to it the constructed object as an inherited attribute., but the lazy() doesn't let me

can I use kwd for this?




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

_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general