Provides parser.
Provides parser.
Required to examine child parsers, and optimize itself out by propagating NadaParser if there is no parser.
Provides unparser.
Provides unparser.
Required to examine child unparsers, and optimize itself out by propagating NadaUnparser if there is no unparser.
This || operator means one of the operands ONLY.
This || operator means one of the operands ONLY. I.e., statically they are supposed to be mutually exclusive, so only one (or none) of them should ever survive.
Sequential composition operator in the grammar.
Sequential composition operator in the grammar.
Note: This should not evaluate the argument unless it has to.
Gram - short for "Grammar Term"
These are the objects in the grammar.
This grammar really differs a great deal from what we find in the DFDL specification because it actually has to be operationalized.
Many of the grammar productions really aren't terribly grammar-like in appearance, because the conditional logic overwhelms the aspects that look like grammar productions.
Another way to think of this as it's just the "second tree". Daffodil starts by creating the DSOM "first tree" which is just the AST (Abstract Syntax Tree) of the DFDL language. Then by way of compiling creates this Gram tree from that which enables a variety of optimizations based on a simple rules-with-guards idiom.
This Gram tree is then a generator of a Parser and an Unparser which incorporate both the parsing/unparsing logic and all RuntimeData structures in their members. If something completely optimizes out then it becomes the EmptyGram which other Gram combinators recognize and optimize out.