Nested structures in phoenix::closure using boost::spirit v1

Suppose I have:
1
2
3
4
5
6
7
8
9
10
11
struct Foo {
   uint32_t x;
};

struct uint_closure : boost::spirit::closure< uint_closure, uint32_t > {
    member1 x;
};

struct foo_closure : boost::spirit::closure< foo_closure, Foo > {
    member1 foo;
};


Now I have the following spirit grammar:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
struct my_grammar : boost::spirit::grammar<my_grammar> {
    my_grammar( Foo& f ) : foo( f ) {}
    Foo& foo;

    template<typename ScannerT>
    struct definition {
        definition( my_grammar const& self ) {
           using namespace boost::spirit;
           using namespace phoenix;

           top = 
                 first_field
              >> ','
              >> second_field
              ;

           first_field =
                 uint_p[ first_field.x = arg1 ]  // this compiles fine
              ;

           second_field =
                 uint_p[ second_field.foo.x = arg1 ] // this does not compile
              ;
        }

        boost::spirit::rule<ScannerT> const& start() const
           { return top; }

        boost::spirit::rule<ScannerT, uint_closure::context_t> first_field;
        boost::spirit::rule<ScannerT, foo_closure::context_t>  second_field;
        boost::spirit::rule<ScannerT>                          top;
    }
}


The second_field rule fails to compile because of the action I've defined.
It seems that I cannot access "nested" members. Anyone have any ideas of
how to solve this short of writing trivial actors like

1
2
3
4
5
6
7
8
9
10
11
12
13
struct assign_foo_x_impl {
    template< typename Target, typename Item >
    struct result {
        typedef Target type;
    }

    template< typename Target, typename Item >
    Target& operator()( Target& c, Item const& item ) const
       { c.x = item; return c; }
};

static phoenix::function<assign_foo_x_impl> const assign_foo_x =
    assign_foo_x_impl();


and then change the second_field rule to:

1
2
3
   second_field =
          uint_p[ assign_foo_x( second_field.foo, arg1 ) ]
       ;


It's just annoying to have to write all of these trivial actors.
Topic archived. No new replies allowed.