Re: (Spirit) Semantic Actions with member functions?
I was able to get boost::bind working to bind the semantic action to the member function of MyGrammar. This seems like a superior solution. In any case, I am not sure how to pass custom data to a functor. When specifing a semantic action I have to pass the type of the functor, which implies that spirit creates a temporary object. Am I missing something?
Its time to switch your global function "myaction" into a functor. Functors are classes that have a function call operator with the same synopsis as your function. The advantage is that one can pass custom data to it via a non-default constructor.
Functors should be and sometimes must be stateless, so care must be employeed to use references in member data.
Slava Akhmechet wrote:
I am playing around with Spirit and I seem to run into an architecture problem with semantic actions. Here's a small example.
class MyGrammar : public grammar<MyGrammar> { public: template <typename ScannerT> struct definition { definition(MyGrammar const& self) { TestRule = str_p("test")[&my_action]; }
rule<ScannerT> const& start() const { return TestRulet; };
private: rule<ScannerT> TestRule; }; };
My major problem is related to the fact that I cannot pass any custom data to my_action function. Since my_action is a global function, it has no knowledge of MyGrammar and must rely on global variables. Ideally, I would pass self to my_action to be able to hold state. What is a general way to get around this problem? The documention mentions a way to specify member functions as semantic action actors using boost's bind facilities but I was unable to get it to work. Thanks in advance.
P.S. Sorry for a fairly newbie question, I was unable to find the answer online or in the docs. P.P.S. I might have accidently double posted this. Sorry about that.
*Yahoo! Groups Sponsor*
http://rd.yahoo.com/M=247865.3269369.4566997.1261774/D=egroupweb/S=170500678...
Info: http://www.boost.org Wiki: http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl Unsubscribe: mailto:boost-users-unsubscribe@yahoogroups.com [mailto:boost-users-unsubscribe@yahoogroups.com>]
Your use of Yahoo! Groups is subject to the Yahoo! Terms of Service http://docs.yahoo.com/info/terms/.
Info: http://www.boost.org Wiki: http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl Unsubscribe: mailto:boost-users-unsubscribe@yahoogroups.com [mailto:boost-users-unsubscribe@yahoogroups.com>]
Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
Slava Akhmechet wrote:
I was able to get boost::bind working to bind the semantic action to the member function of MyGrammar. This seems like a superior solution. In any case, I am not sure how to pass custom data to a functor. When specifing a semantic action I have to pass the type of the functor, which implies that spirit creates a temporary object. Am I missing something?
No, you pass an instance of the functor, which can be cosntructed with arbitrary arguments. struct functor { f(char const *s) : msg(s) {} template<class Iter> void operator(Iter, Iter) { std::cout << this->msg; } char const *msg; }; parse(something, something_p[functor("something")]); -- Rainer Deyke - rainerd@eldwood.com - http://eldwood.com
Rainer Deyke wrote:
Slava Akhmechet wrote:
I was able to get boost::bind working to bind the semantic action to the member function of MyGrammar. This seems like a superior solution. In any case, I am not sure how to pass custom data to a functor. When specifing a semantic action I have to pass the type of the functor, which implies that spirit creates a temporary object. Am I missing something?
No, you pass an instance of the functor, which can be cosntructed with arbitrary arguments.
struct functor { f(char const *s) : msg(s) {} template<class Iter> void operator(Iter, Iter) { std::cout << this->msg; } char const *msg; };
parse(something, something_p[functor("something")]);
The preferred way is to keep the semantic functors as light as possible. As Rainer suggested, a pointer is ok. As for me, I prefer keeping a reference to some external data. Example: struct functor { f(T& data) : data(data) {} template<class Iter> void operator(Iter, Iter); T& data; }; BTW, I suggest continuing this thread here: Spirit-general mailing list Spirit-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spirit-general -- Joel de Guzman joel at boost-consulting.com http://www.boost-consulting.com http://spirit.sf.net
participants (3)
-
Joel de Guzman
-
Rainer Deyke
-
Slava Akhmechet