![]() |
Home | Libraries | People | FAQ | More |
In the grammar defined in the preceding section, the transform associated with non-terminals is a little strange-looking:
proto::when< _ , LeftmostLeaf( proto::_child0 ) // <-- a "callable" transform >
It has the effect of accepting non-terminal expressions, taking the 0th
(leftmost) child and recursively invoking the LeftmostLeaf
function on it. But LeftmostLeaf( proto::_child0
)
is actually a function
type. Literally, it is the type of a function that accepts
an object of type proto::_child0
and returns an object of type LeftmostLeaf
.
So how do we make sense of this transform? Clearly, there is no function
that actually has this signature, nor would such a function be useful.
The key is in understanding how proto::when<>
interprets
its second template parameter.
When the second template parameter to proto::when<>
is a function type, proto::when<>
interprets the function type as a transform. In this case, LeftmostLeaf
is treated as the type
of a function object to invoke, and proto::_child0
is treated as a transform. First, proto::_child0
is applied to the current expression (the non-terminal that matched this
alternate sub-grammar), and the result (the 0th child) is passed as an
argument to LeftmostLeaf
.
![]() |
Note |
---|---|
Transforms are a Domain-Specific Language
|
The type LeftmostLeaf( proto::_child0
)
is an example of a callable
transform. It is a function type that represents a function
object to call and its arguments. The types proto::_child0
and proto::_value
are primitive transforms.
They are plain structs, not unlike function objects, from which callable
transforms can be composed. There is one other type of transform, object
transforms, that we'll encounter next.