
Hi Luke,
Right now it is hard coded that the function object generated by apply_wrap1 takes one argument. I'm pretty sure you could build compile time logic to search for the largest _2, _4 type token and select the specialization of the wrapper that matches the number of arguments used in the expression string. Yes, it is possible. I used the "always take 1 argument" approach to make the example as simple as I could - the goal of this example is the demonstration of how to build callable functions.
You have a comment: /* * The grammar * * expression ::= plus_exp * plus_exp ::= prod_exp ((plus_token | minus_token) prod_exp)* * prod_exp ::= value_exp ((mult_token | div_token) value_exp)* * value_exp ::= int_token | '_' */
And then implement the grammar using metaparse based metaprogramming, eventually declaring your compile time parser with this:
typedef build_parser<entire_input<expression> > function_parser;
I believe we could apply the metaparse library to itself to get a more natural syntax for declaring a metaparser:
typedef build_parser<entire_input<grammar<rule<_S("expression ::= plus_exp")>, rule<_S("plus_exp ::= prod_exp ((plus_token | minus_token) prod_exp)*")>, rule<_S("value_exp ((mult_token | div_token) value_exp)*")>, rule<_S("value_exp ::= int_token | '_'")> >, semantic_action<_S("value_exp"), build_value>, semantic_action<_S("prod_exp"), build_mult>, semantic_action<_S("plus_exp"), build_plus> > > function_parser;
This is essentially what I have in mind when I think of metaparse and constexpr based mpl string used to make metaprogramming easier.
I'd be interested in seeing if you can get the above proposed syntax (or something similar) to compile to demonstrate the metapower of metaparse. A compile time parser for generating compile time parsers.
I've added a new example: meta_metaparse doing this. You can define the grammar the following way: typedef grammar<> ::rule_<_S("plus_token"), token<lit_c<'+'>>>::type ::rule_<_S("minus_token"), token<lit_c<'-'>>>::type ::rule_<_S("mult_token"), token<lit_c<'*'>>>::type ::rule_<_S("div_token"), token<lit_c<'/'>>>::type ::rule_<_S("arg_token"), token<lit_c<'_'>>>::type ::rule_<_S("int_token"), token<int_>>::type ::rule<_S("S"), _S("plus_exp")>::type ::rule<_S("plus_exp"), _S("prod_exp plus_exp_*")>::type ::rule<_S("plus_exp_"), _S("plus_op prod_exp")>::type ::rule<_S("plus_op"), _S("plus_token | minus_token")>::type ::rule<_S("prod_exp"), _S("value_exp prod_exp_*")>::type ::rule<_S("prod_exp_"), _S("prod_op value_exp")>::type ::rule<_S("prod_op"), _S("mult_token | div_token")>::type ::rule<_S("value_exp"), _S("int_token | arg_token")>::type ::semantic_action<_S("int_token"), build_value>::type ::semantic_action<_S("arg_token"), build_arg>::type ::semantic_action<_S("prod_exp"), build_mult>::type ::semantic_action<_S("plus_exp"), build_plus>::type g; typedef build_parser<entire_input<g>> function_parser; Regards, Abel