4

EDIT: I expanded sehe's example to show the problem when I want to use it on another rule: http://liveworkspace.org/code/22lxL7$17

I'm trying to improve the performances of my Boost Spirit parser and I saw that since C++11, it was possible to use auto-rules like that:

auto comment = "/*" >> *(char_ - "*/") >> "*/"; 

(or with BOOST_AUTO or BOOST_SPIRIT_AUTO).

I have a rule declarer like that:

qi::rule<lexer::Iterator, ast::SimpleType()> simple_type;

and defined like that:

simple_type %=
        const_
    >>  lexer.identifier;

If I declare it with auto, it compiles, but it cannot be used as AST in other rules.

Is it possible to define rules creating AST with auto rules ? I'm also interested in other ways to speedup AST creation in Boost Spirit.

ildjarn
  • 62,044
  • 9
  • 127
  • 211
Baptiste Wicht
  • 7,472
  • 7
  • 45
  • 110

2 Answers2

2

First of all, I tried a simple example and "it works for me" with a simple adapted struct:

struct fixed
{
    int integral;
    unsigned fractional;
};

BOOST_FUSION_ADAPT_STRUCT(fixed, (int, integral)(unsigned, fractional));

template <typename It, typename Skipper = qi::space_type>
    struct parser : qi::grammar<It, std::vector<fixed>(), Skipper>
{
    parser() : parser::base_type(start)
    {
        using namespace qi;

        BOOST_SPIRIT_AUTO(qi, fixed_rule, lexeme [ int_ >> -('.' >> uint_ | attr(0u)) ]);
        start = *fixed_rule;

        BOOST_SPIRIT_DEBUG_NODE(start);
    }

  private:
    qi::rule<It, std::vector<fixed>(), Skipper> start;
};

This happily parses the inputs: http://liveworkspace.org/code/22lxL7$1

I think you might mean where attribute compatibility is required, and

should be able to help out just fine in those cases.

See this answer for more details on attr_cast (and attribute compatibility in general): String parser with boost variant recursive wrapper

Community
  • 1
  • 1
sehe
  • 374,641
  • 47
  • 450
  • 633
  • Hi sehe, thanks for the great answer as ever. I tried to use `attr_cast` and `as`, but I did not succeed in using the auto rule in a variant: http://liveworkspace.org/code/22lxL7$17 . Where should I use the `attr_cast` or `as` ? – Baptiste Wicht Mar 10 '13 at 10:05
  • 2
    @BaptisteWicht See [here](http://liveworkspace.org/code/c4yBq%240). I can't make it work with attr_cast. Another important problem with this "micro-rules" is that you can't have cyclic dependencies between them (at least I can't see how) (I mean something like [this](http://www.boost.org/libs/spirit/example/qi/compiler_tutorial/calc4.cpp) where `expression` depends on `term`; `term` on `factor`, and `factor` on `expression`). –  Mar 10 '13 at 10:59
  • @llonesmiz Thanks, you beat me to it. (Good morning) – sehe Mar 10 '13 at 11:01
  • @llonesmiz Thanks, it worked. But I did not think of the limitations with cyclic dependencies, I have plenty of them in my grammar :( – Baptiste Wicht Mar 10 '13 at 11:30
  • That, and I don't think it is possible to debug 'auto' parse expressions (***not*** rules) with BOOST_SPIRIT_DEBUG or similar. – sehe Mar 10 '13 at 11:35
1

There's no such thing as an "auto rule". When you auto-capture an expression like that, you're using all of the defaults to create a rule. So the attribute of this "auto rule" will be exactly and only the attribute of the expression, with no attribute conversion.

If you need to create special attribute data (ie: you need to convert the incoming attribute type to your own data), you must either use a rule or a semantic action.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982