The `LeafPtg` library provides computations that translate simple data
objects into `PTGNode`s for use in building structured text:

$/Output/LeafPtg.gnrc :inst

This macro is attached to a product file.

Computations needed to create a `PTGNode`
representing a string from an attribute named `Sym`
created by `mkidn` are associated with the
symbol `IdPtg` exported by the `LeafPtg` library.
The `PTGNode` created is the value of the `Ptg`
attribute of that symbol.
Thus every `SetName` and `SetElement` node in
Figure 4 can be provided with a `Ptg`
attribute whose value is the string representing
that node in the input text by the attribute grammar fragment:

ATTR Ptg: PTGNode;

SYMBOL Entity INHERITS IdPtg END;

This macro is attached to a product file.

(Remember that both `SetName` and `SetElement`
inherit the computations of `Entity`.)

Note that the boxes in the third row of Figure 4,
all of which contain asterisks, all represent the same number of occurrences.
In other words, there is one `Quoted`,
one `Integer` and one `Name`
for each `Set`.
Also, the diagram states directly that there is one `SetName`
for each `Set`.
These are important insights, because they show us where the information
for the translation comes from.

Figure 4 associates translation computations with only
two nodes other than `SetName` and `SetElement`:
The set size and set definition must be computed at `SetDef`,
and the header file must be constructed and output at `text`.
Each of these computations involves gathering information from descendants,
in the form of either lists or totals.

Because gathering information from descendants is a very common operation,
a special notation for it is provided: `CONSTITUENTS`.
A `CONSTITUENTS` expression specifies an attribute of a descendant that
acts as the ultimate source of the information, and a process for combining
that information from all of the descendants possessing it.
This process is described by a clause of the form
`WITH (Type, Combine, Convert, Create)`.
Here `Type` is the data type of the gathered information, while
`Combine`, `Convert` and `Create`
are functions yielding objects of that data type.
`Combine` takes two `Type` objects and yields the result of combining
them.
`Convert` takes one object of the type of the attribute specified by
the `CONSTITUENTS` expression and converts it to an appropriate `Type`
object.
`Create` creates an appropriate `Type` object from nothing.

The computations associated with `text` and `SetDef` both use
`CONSTITUENTS` expressions heavily:

ATTR Size: int;

SYMBOL text COMPUTE

PTGOut(

PTGHeaderFile(

PTGNumb(CONSTITUENTS SetDef.Ptg WITH (int, ADD, ARGTOONE, ZERO)),

CONSTITUENTS SetName.Ptg WITH (PTGNode, PTGList, PTGQuoted, PTGNull),

CONSTITUENTS SetDef.Size WITH (PTGNode, PTGList, PTGNumb, PTGNull),

CONSTITUENTS SetDef.Ptg WITH (PTGNode, PTGSeq, IDENTICAL, PTGNull),

CONSTITUENTS SetName.Ptg WITH (PTGNode, PTGList, PTGName, PTGNull)));

END;

SYMBOL SetDef COMPUTE

SYNT.Ptg=

PTGSet(

PTGName(CONSTITUENT SetName.Ptg),

CONSTITUENTS SetElement.Ptg WITH (PTGNode, PTGList, PTGQuoted, PTGNull));

SYNT.Size=CONSTITUENTS SetElement.Ptg WITH (int, ADD, ARGTOONE, ZERO);

END;

This macro is attached to a product file.

Consider the computation of `SetDef.Size`.
This computation gathers information from the `Ptg` attributes of all of
the `SetElement` descendants of the `SetDef` node.
It gathers this information by applying `ARGTOONE` to every such attribute
and passing the type-`int` result to that node's parent.
At every node with more than one descendant, the computation applies
`ADD` pairwise to the results from those descendants.
If one of those descendants has no `SetElement` nodes as descendants,
its result is obtained by evaluating the function `ZERO` with no
arguments.

`ADD`, `ARGTOONE` and `ZERO` are all predefined functions.
`ADD` takes two integer arguments and returns the integer sum,
`ARGTOONE` takes one argument and returns the integer `1`,
while `ZERO` takes no arguments and returns the integer `0`.
Thus the effect of the expression
`CONSTITUENTS SetElement.Ptg WITH (int, ADD, ARGTOONE, ZERO)`
is to count the number of `SetElement` descendants of
the `SetDef` node.

`CONSTITUENTS SetElement.Ptg WITH (PTGNode, PTGList, PTGQuoted, PTGNull)`
can be analyzed similarly.
`PTGNull` is a function exported by the structured text creation module.
It yields `PTGNULL`, a distinguished `PTGNode` that represents the
empty string.

The expression `CONSTITUENT SetName.Ptg` is valid if and only if the
current node has exactly one descendant that is a `SetName` node.
It's value is the `Ptg` attribute of that node.
Note that because there is exactly one such descendant, no combining of
information is required.

Finally, `PTGNumb` is a function exported by the
`LeafPtg` library module.
It accepts an argument of type `int` and delivers a
`PTGNode`
representing a sequence of digits giving the value of that argument.