c++ - Order of semantic actions using Spirit (with Phoenix reference) -
i'm building parser execute commands user may enter on command line. first part of command module belongs to, second part module's function call.
attached first parser semantic action (with boost::phoenix::ref()) supposed store name of module in variable m_modulename. attached 2nd parser semantic action calls function printparameters former variable parameter.
#include <boost/spirit/include/phoenix_core.hpp> #include <boost/spirit/include/phoenix_operator.hpp> #include <boost/spirit/home/qi.hpp> #include <boost/bind.hpp> #include <iostream> #include <string> namespace qi = boost::spirit::qi; namespace phoenix = boost::phoenix; void printparameters(const std::string & module, const std::string & command) { std::cout << "module name during parse: " << module << std::endl; std::cout << "command name during parse: " << command << std::endl; } template <typename iterator> struct mycommandparser : public qi::grammar<iterator> { mycommandparser() : mycommandparser::base_type(start) { start = qi::as_string[+(~qi::char_(' '))][phoenix::ref(m_modulename) = qi::_1] >> qi::as_string[+(~qi::char_('\n'))][boost::bind(&printparameters, m_modulename, ::_1)]; }; qi::rule<iterator> start; std::string m_modulename; }; int main() { mycommandparser<std::string::const_iterator> commandgrammar; commandgrammar.m_modulename = std::string("initial_default"); std::cout << "module name before parsing: " << commandgrammar.m_modulename << std::endl; std::string str("mod01 cmd02\n"); std::string::const_iterator first = str.begin(); std::string::const_iterator last = str.end(); qi::parse(first, last, commandgrammar); std::cout << "module name after parsing: " << commandgrammar.m_modulename << std::endl; }
expected result: during first semantic action value of m_modulename should set mod01 should printed during printparameters function.
actual result (program output):
module name before parsing: initial_default module name during parse: command name during parse: cmd02 module name after parsing: mod01
while constructing minimal example noticed value of m_modulename empty during execution of parse function, although has been set "initial_default" beforehand.
can please explain going on here?
why value empty instead of being mod01?
you cannot mix boost bind/phoenix/lambda/qi/std placeholders.
in fact cannot use boost bind inside semantic action.
you want use use phoenix::bind
qi::_1
. aoh, , add phoenix::cref()
around m_modulename
.
other that, don't want use ugly semantic actions in case @ all:
simplified:
#include <boost/spirit/include/qi.hpp> namespace qi = boost::spirit::qi; int main() { std::string const str("mod01 cmd02\n"); std::string modulename, command; qi::parse(str.begin(), str.end(), +~qi::char_(' ') >> +~qi::char_('\n'), modulename, command); std::cout << "module name after parsing: " << modulename << "\n"; std::cout << "command after parsing: " << command << "\n"; }
prints
module name after parsing: mod01 command after parsing: cmd02
see boost_fusion_adapt_struct , boost/fusion/adapted/std_pair.hpp
e.g. ways scale/automate
Comments
Post a Comment