I suppose the missing link might have been
#define BOOST_SPIRIT_USE_PHOENIX_V3
See it live on http://liveworkspace.org/code/3uvyb4$1
It prints
Hello world from 'Grammar::composing(PredicateArgList const&)' args:3
as expected.
UPDATE PS. I'd probably prefer writing the bind invocation like so:
Grammar(): Grammar::base_type(predicate)
{
using phx::bind;
using namespace qi;
as<PredicateArgList> coerce;
predicate =
(pred_tbl > '('
> coerce [ -(primary_expr % ',') ]
> ')')
[ phx::bind(_1, this, _2)]
;
// ...
I think it is much clearer with _1
and _2
instead of the at_c<n>
invocations.
Here is the code for reference:
#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/function.hpp>
#include <boost/phoenix/fusion.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
namespace fusion = boost::fusion;
namespace ascii = boost::spirit::ascii;
namespace phx = boost::phoenix;
namespace AST
{
struct FunctionCall {};
using Value = int;
}
template <typename Iterator>
struct Grammar : qi::grammar<Iterator, AST::FunctionCall(), ascii::space_type>
{
Grammar(): Grammar::base_type(predicate)
{
using phx::bind;
using namespace qi;
as<PredicateArgList> coerce;
predicate =
(pred_tbl > '('
> coerce [ -(primary_expr % ',') ]
> ')')
[ phx::bind(_1, this, _2)]
;
pred_tbl.add
("composing", &Grammar::composing)
;
primary_expr = qi::int_;
}
typedef std::vector<AST::Value> PredicateArgList;
typedef boost::function<void (Grammar*, PredicateArgList const&)> Predicate;
qi::symbols<char, Predicate> pred_tbl;
qi::rule<Iterator, AST::Value(), ascii::space_type> primary_expr;
qi::rule<Iterator, AST::FunctionCall(), ascii::space_type> predicate;
void composing(const PredicateArgList& args)
{
std::cout << "Hello world from 'Grammar::composing(PredicateArgList const&)' args:" << args.size() << "\n";
}
};
int main()
{
const std::string input("composing (1, 2, 3)");
auto f = begin(input), l = end(input);
Grammar<decltype(f)> p;
bool ok = qi::phrase_parse(f,l,p,ascii::space);
return ok?0:255;
}