Association of properties to definitions
The use of any module of this library requires that objects are
identified by keys as computed by the consistent renaming modules.
All modules of this library, except SetFirst , Reflex ,
and PropLib , are instantiated by the same pattern:
$/Prop/ModuleName.gnrc+instance=NAME +referto=KEY :inst
for example
$/Prop/OccCnt.gnrc+instance=Var +referto=CtrlVar :inst
The instance parameter is used to distinguish several instances
of a module that are used in one specification.
If only one instance of a module is used the parameter can be omitted.
The referto parameter is used to specify the name of the
Key attribute, CtrlVarKey in the example above.
The value must be the same as that of the referto parameter
specified for the instance of the consistent renaming module
which computed the Key attribute.
(The referto parameter is usually omitted, unless there are
symbols that have more than one Key attribute.)
The instantiation of the modules SetFirst , Reflex ,
and PropLib is described in the corresponding section.
The modules PropLib and Reflex provide some useful
PDL operations on definition table entries.
All other modules of this library provide some computational role
to be used in .lido specifications. The following applies only
to these modules.
The computational results of each module can be accessed using attributes
in .lido computations, or by application of PDL generated
access functions applied to object keys, as described for each module
individually.
The computations provided by each module ensure that properties
are not accessed before they are set.
For this purpose each module provides a computational role
named NAMERangeModName , where ModName is the
name of the module and NAME is the value of the
instance parameter.
(Exception: in the module OccCnt it is named NAMERangeCnt .)
The root of the grammar automatically inherits this role.
Hence, it need not be used in usual cases.
The condition that all properties are set
is provided by an attribute of the range symbol. It may be used
as a precondition for computations which rely on that fact.
In seldom cases it may be necessary that symbols other than the grammar root
inherit that range role
in order to avoid cyclic dependencies between computations:
if the computation of a property value in one range
of the program depends on the access of a property in another
(e.g. enclosing) range.
Note: The computations of these modules identify program objects
by definition table keys. Hence, ranges specified for
the computation of the keys by a unique renaming module,
e.g. RangeScope , are irrelevant for these modules here.
In our running example we use the OccCnt module to check
for multiply defined identifiers. As it is the first use of this
module we can ommit the instance parameter. Since we
omitted the referto parameter in the instance of the
consistent renaming module that computes the keys, we omit it here, too:
$/Prop/OccCnt.gnrc :inst
The central computations of each module are provided by one or
several computational roles, e.g. NAMECount and NAMETotalCnt
in case of the OccCnt module.
These roles are usually associated to grammar symbols representing
identifier occurrences. In general they may be associated
to any symbol that has a Key attribute.
In order to check for multiply defined identifiers in our running example
both the Count role and the TotalCnt role is associated
to defining identifier occurrences. As there are several symbols
representing defining identifier occurrences which all have to be
checked in the same way, we introduce a new role MultDefChk
that comprises the necessary computations:
SYMBOL MultDefChk INHERITS Count, TotalCnt END;
SYMBOL DefIdent INHERITS MultDefChk END;
SYMBOL ClassDefIdent INHERITS MultDefChk END;
SYMBOL ModDefIdent INHERITS MultDefChk END;
|