Eli   Documents

General Information

 o Eli: Translator Construction Made Easy
 o Global Index
 o Frequently Asked Questions
 o Typical Eli Usage Errors

Tutorials

 o Quick Reference Card
 o Guide For new Eli Users
 o Release Notes of Eli
 o Tutorial on Name Analysis
 o Tutorial on Scope Graphs
 o Tutorial on Type Analysis
 o Typical Eli Usage Errors

Reference Manuals

 o User Interface
 o Eli products and parameters
 o LIDO Reference Manual
 o Typical Eli Usage Errors

Libraries

 o Eli library routines
 o Specification Module Library

Translation Tasks

 o Lexical analysis specification
 o Syntactic Analysis Manual
 o Computation in Trees

Tools

 o LIGA Control Language
 o Debugging Information for LIDO
 o Graphical ORder TOol

 o FunnelWeb User's Manual

 o Pattern-based Text Generator
 o Property Definition Language
 o Operator Identification Language
 o Tree Grammar Specification Language
 o Command Line Processing
 o COLA Options Reference Manual

 o Generating Unparsing Code

 o Monitoring a Processor's Execution

Administration

 o System Administration Guide

Mail Home

Tutorial on Name Analysis

Previous Chapter Next Chapter Table of Contents


Classes with Multiple Inheritance

Our previous examples of modules and with statements can be easily combined to demonstrate the scope rules for object oriented classes with multiple inheritance.

To avoid confusion with the so far specified scope rules we introduce a new language construct for declaration of classes:

Class.con[28]==

Declaration:    'class' DefIdent Inheritances ClassBlock ';'.
ClassBlock:     Compound.
Inheritances:   Inheritance*.
Inheritance:    ':' InheritIdent.
InheritIdent:   Ident.
This macro is attached to a product file.

Applied identifier occurrences within the body of a class are bound to definitions of that range, or to definitions that are visible due to inheritances from other classes (or modules), or to definitions in the ranges that enclose the class declaration.

Hence, the scopes obtained from inheritances are inserted into the environment hierarchy of the class body, as in the case of our with statements.

Since classes that are used for inheritance may inherit from other classes, the inheritance relation must form a partial order. It must not be cyclic. A class c1 may inherit from a class c2 via several paths through the inheritance relation.

That partial order governs hiding of definitions: A definition of an identifier a in the body of a class c hides definitions of a in any class directly or indirectly inherited by c.

Hence, the scope property of a class is the scope of the class body embedded in the environment of the inheritance relation for that class.

Wherever the class identifier is visible it can be used for qualified access, as introduced for modules: A qualified access c::a identifies an a defined in the body of class c or in a class inherited by c according to the inheritance relation.

These scope rules are specified using the techniques of the last two examples: A class has a scope property, as a module has; and a class body inherits other scopes as our with statement does. Hence, the ClassBlock combines the two roles ExportRange and InhRange of the library module.

Class.lido[29]==

SYMBOL ClassBlock INHERITS ExportRange, InhRange END;

RULE: Declaration ::= 'class' DefIdent Inheritances ClassBlock ';' COMPUTE
  ClassBlock.ScopeKey = DefIdent.Key;
  ClassBlock.GotInh = Inheritances CONSTITUENTS InheritIdent.InheritOk;
  Inheritances.InnerScope = ClassBlock.Env;
END;

SYMBOL Inheritances:    InnerScope: Environment;
This macro is attached to a product file.

The Inheritances affect the scope of the class body, like the WithBody in the example above. As there may be several Inheritances the attribute Inheritances.InnerScope is accessed from each. The InheritIdent has the role InheritScope provided by the library module for scope properties already used above. It adds each single inheritance to the inheritance relation of the class scope specified by INCLUDING Inheritances..

The role InheritScope yields an attribute InheritOk. It indicates whether the inheritance relation is not cyclic. It is checked by ChkInherit.

ClassInherit.lido[30]==

SYMBOL InheritIdent INHERITS
        InheritScope, ChkInherit,
        IdUseEnv, ChkIdUse, IdentOcc
COMPUTE
  SYNT.ScopeKey = THIS.Key;
  SYNT.InnerScope = INCLUDING Inheritances.InnerScope;
END;
This macro is attached to a product file.

It has also to be checked that the InheritIdent is bound to an object (class or module) that has a scope property. The role ChkInherit defined above is reused for that purpose.

The library module for scope properties ensures that all relevant inheritances are considered, all relevant scope properties are associated, and all relevant definitions are encountered, before applied identifier occurrences are bound in the class body or in qualified accesses.

We now introduce an additional uniqueness requirement for inheritance: If an applied identifier occurrence is bound to a definition in an inherited environment there must not be a not hidden binding of that identifier in another inherited environment. Such an alternative binding is checked by ChkInhIdUse for all IdUseEnv occurrences and by ChkInhIdUseScopeProp for all IdUseScopeProp occurrences:

UniqueInherit.lido[31]==

SYMBOL UseIdent INHERITS ChkInhIdUse END;
SYMBOL TypeUseIdent INHERITS ChkInhIdUse END;
SYMBOL QualIdent INHERITS ChkInhQualIdUse END;
SYMBOL SelectIdent INHERITS ChkInhQualIdUse END;
This macro is attached to a product file.


Previous Chapter Next Chapter Table of Contents