I have two rules with the same attribute.
Is it possible to pass the attribute of the matrix_ rule to the matrixBlock_ child rule?
I want to keep the repeat directive from creating an attribute of the form vector< >. Instead it should just keep writing into the attribute of matrix_ (numBlocks’s times).
I tried to pass the attribute as inherited attribute to the child rule and it compiles(see below). But I get several “ghost” entries in my vector which come not from the phoenix::push_back.
Also this seems not to be the optimal way for me. Is it possible to us automatic attribute propagation in matrixBlock_ instead of semantic actions?
typedef vector<columnT> Matrix;
matrix_ = repeat(numBlocks)[ matrixBlock_(_val) ];
matrixBlock_ = *column[phoenix::push_back(_r1, _1)];
qi::rule<Iterator, Matrix(), ascii::space_type> matrix_;
qi::rule<Iterator, void(Matrix&), ascii::space_type> matrixBlock_;
Update
to clarify the question:
if I write the rule with no semantic actions the synthesized attribute of matrix_ would be
vector< vector< columnT > >
–
typedef vector<columnT> Matrix;
matrix_ = repeat(numBlocks)[ matrixBlock_ ];
matrixBlock_ = *column;
qi::rule<Iterator, Matrix(), ascii::space_type> matrix_;
qi::rule<Iterator, Matrix(), ascii::space_type> matrixBlock_;
I want it to have the same attribute type as matrixBlock_, a 1-dimansional array.
my actual solution is to use only one rule. (looks to easy 🙂 )
typedef vector<columnT> Matrix;
matrix_ = repeat(numBlocks)[ *column_[ phoenix::push_back(_val, _1) ] ];
//matrixBlock_ = *column;
qi::rule<Iterator, Matrix(), ascii::space_type> matrix_;
//qi::rule<Iterator, Matrix(), ascii::space_type> matrixBlock_;
Update
I was able to reproduce the the phantom entries with this code in vs2010 and boost 1.46.1
http://liveworkspace.org/code/505091dc4631a379763567168a728e0c
output was: 42, 45, -9, 3, 2, 1, 12, 34, 56, 0, 0, 0
My mistake was using an old Boost version. There are no phontoms with 1.5.
Now I have two working versions of my grammar. Is it possible to redesign the grammar without the use of the push_back semantic action?
Updated
Answering your edited question: Yes you can do this without semantic actions, doing simply:
Note that you may want to validate the number of rows/columns. See my extended sample, which uses an extra semantic action to check that (note the subtle change from
*int_to+int_to avoid empty rows):Old answer:
Yes, you can use Spirit’s customization points to treat your user-defined type as a container. The documentation entry I’d suggest for this is here:
Here is a simple example showing how to use it, live:
Full code sample:
Output:
Update
A little more background:
Of course, for a trivial example like this, that just wraps a standard supported container type, it would be fairly easy to employ fusion adaptation instead: ( http://liveworkspace.org/code/56aea8619867451a21cd49fddb1e93bd )
Note that the
qi::epsis necessary due to a bug (AFAICT) with structs that contain only one data element. See e.g. discussion here (and some other mentions)