X3: sequence to vector at end of struct?

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

X3: sequence to vector at end of struct?

Mario Lang
Hi.

Is this supposed to fail?  It current does fail with:

include/boost/spirit/home/x3/operator/detail/sequence.hpp:143:9: error: static assertion failed: Attribute does not have the expected size.

#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/home/x3.hpp>

struct A {
  std::string name;
  std::vector<int> data;
};

BOOST_FUSION_ADAPT_STRUCT(A, (std::string, name) (std::vector<int>, data) )

int main()
{
  using namespace boost::spirit::x3;
  std::string const input = "hello 1 2";
  auto iter = input.begin();
  A a;
  auto const success = parse(iter, input.end(), (char_ - ' ') >> int_ >> int_, a);
}

--
CYa,
  ⡍⠁⠗⠊⠕

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

Re: X3: sequence to vector at end of struct?

Joel de Guzman
On 6/4/15 4:30 AM, Mario Lang wrote:

> Hi.
>
> Is this supposed to fail?  It current does fail with:
>
> include/boost/spirit/home/x3/operator/detail/sequence.hpp:143:9: error: static assertion failed: Attribute does not have the expected size.
>
> #include <boost/fusion/include/adapt_struct.hpp>
> #include <boost/spirit/home/x3.hpp>
>
> struct A {
>    std::string name;
>    std::vector<int> data;
> };
>
> BOOST_FUSION_ADAPT_STRUCT(A, (std::string, name) (std::vector<int>, data) )
>
> int main()
> {
>    using namespace boost::spirit::x3;
>    std::string const input = "hello 1 2";
>    auto iter = input.begin();
>    A a;
>    auto const success = parse(iter, input.end(), (char_ - ' ') >> int_ >> int_, a);
> }

I think you missed a kleene here?: *(char_ - ' ')

Anyway, I see your point. Partitioning that will be very tricky! I guess you
are assuming that the left will take the std::string and the right will
take the std::vector<int>. Unfortunately, attribute compatibility only
happens at the top level, not the subnodes. In the first place, an expression
such as:

   a >> b >> c

is combined, using C++ rules, as:

   seq(seq(a, b), c)

I don't know how to partition the vector attribute to b and c without
some very complex TMP, which I want to avoid.

Hence, I think I should make it clear that attribute compatibility can happen
only at the the top level. It is easy to create a sub-rules for b >> c
anyway that will make it top level:

    r_def = b >> c;
    x_def = a >> rdef;

Thoughts?

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
Reply | Threaded
Open this post in threaded view
|

Re: X3: sequence to vector at end of struct?

Mario Lang
Joel de Guzman <[hidden email]> writes:

> On 6/4/15 4:30 AM, Mario Lang wrote:
>> Hi.
>>
>> Is this supposed to fail?  It current does fail with:
>>
>> include/boost/spirit/home/x3/operator/detail/sequence.hpp:143:9: error: static assertion failed: Attribute does not have the expected size.
>>
>> #include <boost/fusion/include/adapt_struct.hpp>
>> #include <boost/spirit/home/x3.hpp>
>>
>> struct A {
>>    std::string name;
>>    std::vector<int> data;
>> };
>>
>> BOOST_FUSION_ADAPT_STRUCT(A, (std::string, name) (std::vector<int>, data) )
>>
>> int main()
>> {
>>    using namespace boost::spirit::x3;
>>    std::string const input = "hello 1 2";
>>    auto iter = input.begin();
>>    A a;
>>    auto const success = parse(iter, input.end(), (char_ - ' ') >> int_ >> int_, a);
>> }
>
> I think you missed a kleene here?: *(char_ - ' ')

Yes.  I also missed to make it phrase_parse.  And I probably should have
made the example simpler, since the string is already a container.

struct A { char c; std::vector<int> v; };
phrase_parse(..., char_ >> int_ >> int_, space, a);

> Anyway, I see your point. Partitioning that will be very tricky! I guess you
> are assuming that the left will take the std::string and the right will
> take the std::vector<int>. Unfortunately, attribute compatibility only
> happens at the top level, not the subnodes. In the first place, an expression
> such as:
>
>    a >> b >> c
>
> is combined, using C++ rules, as:
>
>    seq(seq(a, b), c)

That, I have understood by now.  My probably naive thought was, that
get_sequence_types actually already flattend this to:

  mpl::vector<T, U, U>

If the attribute is fusion::<T, std::vector<U>>, I was hoping the special case
of a too long attribute type which ends with consecutive equal types on
one side and a vector of that type on the other side could be handled.

> I don't know how to partition the vector attribute to b and c without
> some very complex TMP, which I want to avoid.
>
> Hence, I think I should make it clear that attribute compatibility can happen
> only at the the top level.

That is why I ask, since it wasn't clear to me how far sequence to
vector collapsing would go structurally.

> It is easy to create a sub-rules for b >> c anyway that will make it
> top level:
>
>     r_def = b >> c;
>     x_def = a >> rdef;

Yes, that's what I did/do.

--
CYa,
  ⡍⠁⠗⠊⠕

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