An attribute of a node type T
with value of type U
, supported by a memo
table and circularity test.
An attribute of a node type T
with value of type U
, supported by a memo
table and circularity test. The value of the attribute is computed by
the function f
. The result is memoised so that it is only evaluated once.
f
should not itself require the value of this attribute. If it does, a
circularity error is reported by throwing an IllegalStateException
.
A cached dynamic attribute of a node type T
with value of type U
, supported
by a memo table and circularity test.
A cached dynamic attribute of a node type T
with value of type U
, supported
by a memo table and circularity test. The value of the attribute is initially
computed by the function f
, but the definition can be augmented dynamically.
The result is memoised so that it is only evaluated once for a given definition.
The attribute definition should not itself require the value of this attribute.
If it does, a circularity error is reported by throwing an IllegalStateException
.
This kind of attribute encapsulates state to keep track of the current definition,
so an instance should only be used from one thread at a time.
A variation of the CachedAttribute
class for parameterised attributes.
An attribute of a node type T
with value of type U
which has a circular
definition.
An attribute of a node type T
with value of type U
which has a circular
definition. The value of the attribute is computed by the function f
which may itself use the value of the attribute. init specifies an
initial value for the attribute. The attribute (and any circular attributes
on which it depends) are evaluated until no value changes (i.e., a fixed
point is reached). The final result is memoised so that subsequent evaluations
return the same value.
This code implements the basic circular evaluation algorithm from "Circular Reference Attributed Grammars - their Evaluation and Applications", by Magnusson and Hedin from LDTA 2003.
A constant attribute of a node type T
with value of type U
.
A constant attribute of a node type T
with value of type U
. The
value is given by the computation u
which is evaluated at most once.
Define a cached attribute of T
nodes of type U
by the function f
,
which should not depend on the value of this attribute.
Define a cached attribute of T
nodes of type U
by the function f
,
which should not depend on the value of this attribute. The computed
attribute value is cached so it will be computed at most once.
Define a circular attribute of T
nodes of type U
by the function f
.
Define a circular attribute of T
nodes of type U
by the function f
. f
is allowed to depend on the value of this
attribute, which will be given by init
initially and will be evaluated
iteratively until a fixed point is reached (in conjunction with other
circular attributes on which it depends). The final value is cached.
Define a constant attribute of T
nodes of type U
given by the value
u
.
Define a constant attribute of T
nodes of type U
given by the value
u
. u
is evaluated at most once.
Define a cached dynamic attribute of T
nodes of type U
by the partial
function f
, which should not depend on the value of this attribute.
Define a cached dynamic attribute of T
nodes of type U
by the partial
function f
, which should not depend on the value of this attribute.
The computed attribute value is cached so it will be computed at most once.
Implicitly converts functions to dynamic attributes.
Implicitly converts functions to dynamic attributes. This conversion allows us to use simpler types for dynamic attributes, but still extend them later.
Define a parameterised attribute of T
nodes of type U
by the function
f
, which takes an argument of type V
.
Define a parameterised attribute of T
nodes of type U
by the function
f
, which takes an argument of type V
. The computed attribute value
for a given V
and T
pair is cached so it will be computed at most
once.
Reusable implementation of attribution of syntax trees in a functional style with attribute values cached so that each value is computed at most once. Use an instance of this module to encapuslate related attributes.
You should ensure that more than one circular attribute evaluation from a single module is not executing at the same time because the current implementation has shared state between related circular attributes. If your attributes are unrelated (i.e., can't possibly call each other) you should base them on different attribution module instances and then it is safe for attributes from different collections to execute in parallel.