Boost logo

Boost Users :

From: Hugh Hoover (hugh_at_[hidden])
Date: 2007-01-02 20:09:08


I'm trying to build a parser that does a fairly simple transformation
of an input string - kind of like an L-System.
I can get rules to properly match the input string, but I'm having
real trouble with DOING anything. For testing,
I've created some simple actions and a grammar (and rules) with a
closure. When I don't use the closure for
"temporary" variables, I seem to be able to proceed, but when I do
anything except assign a value to my closure
result, I'm getting failures to compile. This is using gcc4.01 on
MacOSX and spirit 1.8.3 (from boost 1.34).

The specific compiler error is:
../../src/lsystem/catalog_lsystem.cpp: In member function 'void
do_appender::act(T&, const IteratorT&, const IteratorT&) const [with
T = phoenix::actor<phoenix::closure_member<0,
phoenix::closure<String, size_t, String> > >, IteratorT =
__gnu_cxx::__normal_iterator<char*, std::basic_string<char,
std::char_traits<char>, std::allocator<char> > >]':
<snip>
../../src/lsystem/catalog_lsystem.cpp:211: error: no matching
function for call to 'std::basic_string<char, std::char_traits<char>,
std::allocator<char> >::basic_string
(phoenix::actor<phoenix::closure_member<0, phoenix::closure<String,
size_t, String> > >&)'

 From the error, it appears that I need some transformation from
phoenix::actor
back into my closure member, which is a String (typedef for
std::basic_string<char>).

Any suggestions?

do_appender (a simple example actor) looks like:

     struct do_appender {
         template <typename T, typename ValueT>
         void act(T& ref, ValueT const &val) const
         {
             ref += val;
         }

         template <typename T, typename IteratorT>
         void act(T& ref, IteratorT const &first, IteratorT const &
last) const
         {
             String s(first, last);
             ref += s;
         }
     };

     template <typename T>
         inline ref_value_actor<T, do_appender>
         do_append(T& lhs)
     {
         return ref_value_actor<T, do_appender>(lhs);
     }

     template <typename T, typename ValueT>
         inline ref_const_ref_actor<T, ValueT, do_appender>
         do_append(T& lhs, ValueT const& val)
     {
         return ref_const_ref_actor<T, ValueT, do_appender>(lhs,val);
     }

and the closure and grammar (stripped slightly) look like:

     struct ProductionClosure :
boost::spirit::closure<ProductionClosure, String, size_t, String>
     {
         member1 m_result;
         member2 m_count;
         member3 m_temporary;
     };

     struct ParameterLSystem::ProductionGrammar
         : public grammar<ParameterLSystem::ProductionGrammar,
ProductionClosure::context_t>
     {
         String * m_append;

         ProductionGrammar(String * ap) : m_append(ap) {}

         template <typename ScannerT>
         struct definition {
             typedef rule<ScannerT, ProductionClosure::context_t>
rule_t;
             typedef rule<ScannerT> srule_t;
             srule_t r_segment;
             rule_t r_segments;
             srule_t r_leaf;
             rule_t r_leaves;
             srule_t r_push;
             srule_t r_pop;
             rule_t r_start;
             rule_t r_terminalLeaves;
             rule_t r_branch;
             rule_t r_top;

             definition(ProductionGrammar const& self)
             {
                 // basics
                 r_leaf = ch_p('L');

                 r_leaves = (+r_leaf)[r_leaves.m_result =
construct_<String>(arg1, arg2)];

                 r_segment = ch_p('S');

                 r_segments = (+r_segment)[r_segments.m_result =
construct_<String>(arg1, arg2)];

                 r_push = ch_p('[');

                 r_pop = ch_p(']');

                 r_terminalLeaves = r_push[do_append
(r_terminalLeaves.m_result)];

                 r_top = r_branch[self.m_result = arg1];

             }

             rule_t const& start() const {
                 return r_top;
             }
         };
     };
};

String is a typedef for std::basic_string<char> in my namespace.

When I use m_append for a "temporary", I can get things to "work", i.e.,
it compiles and generates the correct output but the grammar will get
more complex
and I don't believe I can get away without using a closure variable.

The full error stack from the compiler is:
../../src/lsystem/catalog_lsystem.cpp: In member function 'void
do_appender::act(T&, const IteratorT&, const IteratorT&) const [with
T = phoenix::actor<phoenix::closure_member<0,
phoenix::closure<String, size_t, String> > >, IteratorT =
__gnu_cxx::__normal_iterator<char*, std::basic_string<char,
std::char_traits<char>, std::allocator<char> > >]':
../../../../opensource/opt/include/boost/spirit/actor/
ref_value_actor.hpp:59: instantiated from 'void
boost::spirit::ref_value_actor<T, ActionT>::operator()(const
IteratorT&, const IteratorT&) const [with IteratorT =
__gnu_cxx::__normal_iterator<char*, std::basic_string<char,
std::char_traits<char>, std::allocator<char> > >, T =
phoenix::actor<phoenix::closure_member<0, phoenix::closure<String,
size_t, String> > >, ActionT = do_appender]'
../../../../opensource/opt/include/boost/spirit/core/scanner/
scanner.hpp:146: instantiated from 'static void
boost::spirit::attributed_action_policy<boost::spirit::nil_t>::call
(const ActorT&, boost::spirit::nil_t, const IteratorT&, const
IteratorT&) [with ActorT =
boost::spirit::ref_value_actor<phoenix::actor<phoenix::closure_member<0,
  phoenix::closure<String, size_t, String> > >, do_appender>,
IteratorT = __gnu_cxx::__normal_iterator<char*,
std::basic_string<char, std::char_traits<char>, std::allocator<char>
> >]'
../../../../opensource/opt/include/boost/spirit/core/scanner/
scanner.hpp:161: instantiated from 'void
boost::spirit::action_policy::do_action(const ActorT&, AttrT&, const
IteratorT&, const IteratorT&) const [with ActorT =
boost::spirit::ref_value_actor<phoenix::actor<phoenix::closure_member<0,
  phoenix::closure<String, size_t, String> > >, do_appender>, AttrT =
boost::spirit::nil_t, IteratorT = __gnu_cxx::__normal_iterator<char*,
std::basic_string<char, std::char_traits<char>, std::allocator<char>
> >]'
../../../../opensource/opt/include/boost/spirit/core/composite/
actions.hpp:109: instantiated from 'typename
boost::spirit::parser_result<boost::spirit::action<ParserT, ActionT>,
ScannerT>::type boost::spirit::action<ParserT, ActionT>::parse(const
ScannerT&) const [with ScannerT =
boost::spirit::scanner<__gnu_cxx::__normal_iterator<char*,
std::basic_string<char, std::char_traits<char>, std::allocator<char>
> >, boost::spirit::scanner_policies<boost::spirit::iter_policy_t,
boost::spirit::match_policy, boost::spirit::action_policy> >, ParserT
=
boost::spirit::rule<boost::spirit::scanner<__gnu_cxx::__normal_iterator<
char*, std::basic_string<char, std::char_traits<char>,
std::allocator<char> > >,
boost::spirit::scanner_policies<boost::spirit::iter_policy_t,
boost::spirit::match_policy, boost::spirit::action_policy> >,
boost::spirit::nil_t, boost::spirit::nil_t>, ActionT =
boost::spirit::ref_value_actor<phoenix::actor<phoenix::closure_member<0,
  phoenix::closure<String, size_t, String> > >, do_appender>]'
../../../../opensource/opt/include/boost/spirit/core/non_terminal/
impl/rule.ipp:233: instantiated from 'typename
boost::spirit::match_result<ScannerT, ContextResultT>::type
boost::spirit::impl::concrete_parser<ParserT, ScannerT,
AttrT>::do_parse_virtual(const ScannerT&) const [with ParserT =
boost::spirit::action<boost::spirit::rule<boost::spirit::scanner<__gnu_c
xx::__normal_iterator<char*, std::basic_string<char,
std::char_traits<char>, std::allocator<char> > >,
boost::spirit::scanner_policies<boost::spirit::iter_policy_t,
boost::spirit::match_policy, boost::spirit::action_policy> >,
boost::spirit::nil_t, boost::spirit::nil_t>,
boost::spirit::ref_value_actor<phoenix::actor<phoenix::closure_member<0,
  phoenix::closure<String, size_t, String> > >, do_appender> >,
ScannerT = boost::spirit::scanner<__gnu_cxx::__normal_iterator<char*,
std::basic_string<char, std::char_traits<char>, std::allocator<char>
> >, boost::spirit::scanner_policies<boost::spirit::iter_policy_t,
boost::spirit::match_policy, boost::spirit::action_policy> >, AttrT =
String]'
../../src/lsystem/catalog_lsystem.cpp:547: instantiated from here
../../src/lsystem/catalog_lsystem.cpp:211: error: no matching
function for call to 'std::basic_string<char, std::char_traits<char>,
std::allocator<char> >::basic_string
(phoenix::actor<phoenix::closure_member<0, phoenix::closure<String,
size_t, String> > >&)'



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net