0

I have this grammar

template<typename Iterator>
struct brainDSL : qi::grammar<Iterator, _problem(), ascii::space_type>
{
    brainDSL() : base_type(p_rule)
    {
        p_rule = problem_;
    }

    qi::rule<Iterator, _problem(), ascii::space_type> p_rule;
};

And these are the parsers:

struct type_ : qi::symbols<char, _problem::_type>
{
    type_()
    {
        add
            ("single_stage", _problem::_type::single_stage)
            ("two_stage", _problem::_type::two_stage)
            ("multi_stage", _problem::_type::multi_stage)
        ;
    }
} type_;

struct command_ : qi::symbols<char, _problem::_command>
{
    command_()
    {
        add
            ("maximize", _problem::_command::maximize)
            ("minimize", _problem::_command::minimize)
        ;
    }
} command_;

auto name_ = qi::lexeme[*(qi::char_ - ':')];

auto problem_ =
    type_
    >> command_
    >> name_ >> ':'
;

I would add the structs and the fusion macro, but I don't think it's necessary. Executing this against a test string, this code compiles correctly but raises an exception inside boost.

If I remove the name_ parser and leave problem_ like this:

auto problem_ =
        type_
        >> command_
    ;

It matches correctly. But if I add anything, even qi::eps, I get exceptions again:

auto problem_ =
        type_
        >> command_
        >> qi::eps
    ;

What is the underlying rule from Boost Spirit I'm violating here?

sehe
  • 374,641
  • 47
  • 450
  • 633
villasv
  • 6,304
  • 2
  • 44
  • 78
  • 1
    http://stackoverflow.com/a/22027181/2417774 – llonesmiz Nov 27 '15 at 05:43
  • I have considered that, but I thought I could not be because of that because moving the definition to inside the ctor but keeping the `auto` fixes the problem. Could still be related to auto, though. I'll try with deep_copy and see the results. – villasv Nov 27 '15 at 05:50
  • 1
    Try just changing `auto name_ = boost::proto::deep_copy(qi::lexeme[*(qi::char_ - ':')]);`. You may need to include `boost/proto/deep_copy.hpp`. – llonesmiz Nov 27 '15 at 05:52
  • @cv_and_he yes, it worked fine. I guess I have to `copy` everytime I want `auto`, but sehe says that Spirit X3 allows `auto` so I guess I'll just try to upgrade my code while its still young. – villasv Nov 27 '15 at 05:54
  • Probably a good idea. In the future having something we can (almost) compile helps a lot when the problem is not obvious. – llonesmiz Nov 27 '15 at 05:56

1 Answers1

1

Just to not let the question unanswered, I'll also add some remarks about the post-solution conditions.

The best solution was to move to Spirit X3, which fully supports use of auto and lambdas, as suggested by @sehe.

The few significant changes I had to make:

  • symbols now take only one template parameter, which is the type it maps.
  • X3 has no grammar, only rules
  • the tutorial I was following suggested the use of macros to define rules. This is bad idea on MSVC and it is better to just use construction followed by definition

Example:

auto r = rule<...> { "Name" }
       = definition;
villasv
  • 6,304
  • 2
  • 44
  • 78