Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: added notes about backpointers issues

...

This is the style one would commonly see as the pattern for the way constructors are called.

NOTE: If the parent node is always passed to the ChildNode so that the child node has a unique backpointer to the parent, then it is impossible to share the child node. This pattern is fine for trees of nested constructs. But when an object references another top-level definition by name, that should not be mistaken for a parent-child relationship.

Attribute Grammars

An old compiler technique is something called attribute grammars. Attribute here is used in a general sense. Nothing to do with XML attributes.

...

We don't really need to care much about this inherited versus synthesized characterization. It's just worth mentioning that the power of the technique comes from the fact that there are these top-down/ancestor as well as bottom-up attribute calculations.

Caution on Inherited Attributes: A sharable construct in the DFDL language should not have a unique context pointer back to its point of reference. Such a mistake is costly because it makes sharing anything impossible. Inherited attributes are trivial to compute, but the lack of any ability to share substructure can result in exponential expansion of the size of the data structure that represents the AST, and also it makes recursive behavior in the language impossible for the compiler using OOLAG. In general, a construct has a lexical parent, and optionally, has a number of points of use that share an object corresponding to the definition. Inherited attributes must take ALL the points of reference into consideration.

Lazy Evaluation versus Passes

Attribute calculations can be complicated. Knowing exactly when all the prerequisite calculations have been completed, such that one knows when one can compute any give given attribute is hard. Attribute grammars carefully divide the world into top-down and bottom-up calculations to facilitate organizing the calculations into passes. Compilers generally have many passes, each of which computes a few more attributes, or constructs a new representation of the data (which is typically, another attributed-tree of slightly different shape/design).

...

There are a few more details required to deal with errors though. There's a separate wiki page on OOLAG - Object-Oriented Lazy Attribute Grammars, which discusses some of this also.

Above we pointed out one must stick with a pure functional programming style to make this all hang together.  This means we need a technique for dealing with the fact that things can go wrong in a compiler. The input source may have errors in it, and good diagnostic messages must be presented back to the author of that DFDL schema.

...

  • OOLAG is a compiler-writers pattern
  • It requires functional programming to avoid the need for organizing code into passes
  • It requires use of special value objects that allow an ordinary value, a set of error/diagnostic objects, or both to be the "answer" of a calculation.
    • Every such value object can answer the 'isError' test.
  • Code is structured into OOLAGValue calculations (using the LV idiom) and OOLAGHost objects

  • OOLAGHost objects carry required evaluations that must be evaluated to insure they are 'done'

     

 

 

 

 

...