Attribute declarations
Quick examples:
synthesized attribute pp :: Document;
inherited attribute env<a> :: Map<String a>;
Attribute declarations begin by indicating whether the attribute is synthesized
or inherited
, give a name for the attribute, and the type of the attribute.
Attributes may also be parameterized in their types.
If they are not parameterized, the angle brackets are omitted:
synthesized attribute name < type variables... > :: type; inherited attribute name < type variables... > :: type;
All type variables that appear in the type must be declared in the type parameter list.
For an explanation of the role of attributes, see the section on attribute grammars. A deeply related concept is the occurs-on declaration.
Attributes that may have their value influenced by aspects are called collection attributes, and are declared by giving the attribute an associated composition operator using with
:
synthesized attribute errors :: [Message] with ++;
This operator must be either ++
(for lists or strings), ||
, &&
, or any user-defined function of type (a ::= a a)
.
In practice, this is almost always list append.
See collection attributes.
Some repetitive idioms exist in synthesized attribute specifications that we would like to avoid writing boilerplate for by hand. These attributes fall into various common patterns (“functor”, “monoid”, etc.)
A set of extensions to Silver allows for such attributes to be specially declared, and a new statement propagate attr1, attr2, ...;
to
be used to specify on a production or nonterminal that equations for the attributes should be automatically generated.
See automatic attributes.
Attributes declarations and occurs-on declarations can be merged:
synthesized attribute pp :: String occurs on Expr, Stmt;
However, this should not be used in any circumstance where the nonterminal and the occurs-on declarations can be merged instead. (See the nonterminal documentation for that syntax.) For more reasons that just the stylistic: this syntax is more inflexible for parameterized attributes.
Example: To demonstrate the inflexibility, the following code will raise an error:
synthesized attribute ast<a> :: a occurs on ConcreteExpr;
Because there is no place where we are able to describe what the type parameter of the
ast
attribute should be onConcreteExpr
.