| Home | Libraries | People | FAQ | More

##### Matching Vararg Expressions

Not all of C++'s overloadable operators are unary or binary. There is the oddball `operator()` -- the function call operator -- which can have any number of arguments. Likewise, with Proto you may define your own "operators" that could also take more that two arguments. As a result, there may be nodes in your Proto expression tree that have an arbitrary number of children (up to ``BOOST_PROTO_MAX_ARITY``, which is configurable). How do you write a grammar to match such a node?

For such cases, Proto provides the `proto::vararg<>` class template. Its template argument is a grammar, and the `proto::vararg<>` will match the grammar zero or more times. Consider a Proto lazy function called `fun()` that can take zero or more characters as arguments, as follows:

    struct fun_tag {};
    struct FunTag : proto::terminal< fun_tag > {};
    FunTag::type const fun = {{}};

    // example usage:
    fun();
    fun('a');
    fun('a', 'b');
    ...

Below is the grammar that matches all the allowable invocations of `fun()`:

    struct FunCall
      : proto::function< FunTag, proto::vararg< proto::terminal< char > > >
    {};

The `FunCall` grammar uses `proto::vararg<>` to match zero or more character literals as arguments of the `fun()` function.

As another example, can you guess what the following grammar matches?

    struct Foo
      : proto::or_<
            proto::terminal< proto::_ >
          , proto::nary_expr< proto::_, proto::vararg< Foo > >
        >
    {};

Here's a hint: the first template parameter to `proto::nary_expr<>` represents the node type, and any additional template parameters represent child nodes. The answer is that this is a degenerate grammar that matches every possible expression tree, from root to leaves.