2

I am currently reading into Boost Spirit and I am being confused by the term "attribute" that is used a lot, but is not defined beforehand. From this and some searching it seems to me that it is a common term in parsing, but I can't find a definition or description of the term.

I think it is something like the result of a parsing step, but I would like a clear and precise definition.

sehe
  • 374,641
  • 47
  • 450
  • 633
Oebele
  • 581
  • 1
  • 4
  • 17
  • Usually this means a value associated with a tree node. The real questions are, why do this? What values can be associated? What can you do with them? This SO answer provides some context: http://stackoverflow.com/a/5768686/120163 I don't know how Boost works with attributes. – Ira Baxter Mar 11 '16 at 23:51

1 Answers1

1

An attribute is the product of a parser.

Synthesis

Each parser has an exposed attribute.

When you combine parsers in expressions, the resulting attributes will be combined into what is called the synthesized attribute. E.g. int_ >> double_ synthesizes into a tuple of (int, double)¹.

Propagation

When exposed attributes get propagated to the surrounding rule context, a lot of automatic compatibility rules and transformations are possible e.g. like in

qi::rule<It, std::string()> r1 = +qi::char_; // std::vector<char> -> std::string

qi::rule<It, boost::optional<int>()> r2 = qi::int_;

qi::rule<It, map<int, double>() > r3 = (qi::int_ >> qi::double) % ';'; // requires `boost/fusion/adapted/std_pair.hpp`

Bound Attribute References

This is a slightly confusing different meaning of attributes;

The parser API accepts variable numbers of arguments that will receive the resulting values from the parse.

These are known as the "bound attributes". The context will actually refer directly to them. The same compatibility/propagation rules apply as above, making it possible to do this directly:

using namespace qi;
std::map<std::string, int> data;
bool ok = phrase_parse(f, l, 'keyvalues: ' >> (lexeme[+alpha] >> '=' >> int_) % ';', space, data);

Extending

The transformations and compatibility rules can be customized for user-defined types. It's a bit beyond the scope here, but documentation can be found here: docs and [SO] hosts a good number of examples the demonstrates their use.

Links

The documentation lists the types synthesized with each operator/directive.

See also Detecting the parameter types in a Spirit semantic action


¹ technically it could be boost::fusion::vector2<int, double> but you shouldn't care about this implementation detail; attribute propagation rules hide this detail from you

Community
  • 1
  • 1
sehe
  • 374,641
  • 47
  • 450
  • 633