General Information

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

Tutorials

 o Quick Reference Card
 o Guide For new Eli Users
 o Release Notes of Eli
 o Tutorial on Name Analysis
 o Tutorial on Type Analysis

Reference Manuals

 o User Interface
 o Eli products and parameters
 o LIDO Reference Manual

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

 Questions, Comments, ....

Tutorial on Type Analysis

Previous Chapter Next Chapter Table of Contents


Record Types

We now introduce record types to our language in order to demonstrate how composed program defined types are specified. A record type is described by a sequence of field declarations which have the same form as ObjDecls used in variable declarations. The notation of variables is extended by an alternative for component selection from a variable.

The following concrete productions are added:

ScopeProp.con[35]==


TypeDenoter:    RecordType.
RecordType:     'record' ObjDecls 'end'.
Variable:       Variable '.' SelectIdent.
SelectIdent:    Ident.

This macro is attached to a product file.

Here is an example program that defines and uses a record variable rv: RecordExamp[36]==

begin
  var   record int i, bool b, real r end rv;
  var   int j, bool c, real s;
  j = rv.i;
  c = rv.b;
  s = rv.r;
end

This macro is attached to a product file.

An abstraction of a record type is the sequence of component definitions. The selection construct needs to identify a definition within such a sequence. Hence it is suitable to use a scope for that abstraction. The module AlgScopeProp supports using scopes as properties, in particular for describing types.

ScopeProp.specs[37]==


$/Name/AlgScopeProp.gnrc:inst

This macro is attached to a product file.

A RecordType introduces a new type in a program, different from any other type. That concept is represented by the role TypeDenotation of the Typing module.

In a different language we could have specified that the notation of one record type is equal or compatible to another notation of a record type at a different place in the program, e. g. if they have the same sequence of component (structural equality). In that case we had to describe the rules for equality or compatibility in the EqualTypes or CompatibleTypes functions; but we would use the same specification as given below. We have to decide this question of type equality for every form of TypeDenoter in the language.

The role RangeScopeProp of the AlgScopeProp module specifies the RecordType to be a range. Its scope of component definitions is associated to the ScopeKey. The ScopeKey is specified to be the type key created by the role TypeDenotation.

ScopeProp.lido[38]==


RULE: TypeDenoter ::= RecordType COMPUTE
  TypeDenoter.Type = RecordType.Type;
END;

SYMBOL RecordType INHERITS 
        TypeDenotation, RangeScopeProp 
COMPUTE
  SYNT.ScopeKey = SYNT.Type;
  SYNT.GotType = ResetTypeName (SYNT.Type, "record...");
END;

This macro is attached to a product file.

The last computation above set the TypeName property of the created type for the facility of printing type information we have introduced above. The attribute GotType is provided by the TypeDenotation role, indicating that all relevant properties of the created type are set. The module then takes care that those properties are set when they are accessed for objects having that type. (The scope property need not be included in that mechanism, because the AlgScopeProp module takes care for setting the scope property before using it.

Type analysis for a record component selection is specified in the following way: The Variable a selector is applied to has to have a record type. In our case that is decided by checking that the type of the Variable has the Scope property being set. The selection identifier is to be bound in that scope. We set the attribute SelectIdent.Scope to that scope in order to use a role of the AlgScopeProp module for binding.

Finally, the type of the whole selection is the type of the bound component:

Selection.lido[39]==


RULE: Variable ::= Variable '.' SelectIdent COMPUTE
  SelectIdent.Scope = 
     GetScope (Variable[2].Type, NoEnv)
     <- INCLUDING Program.GotScopeProp;

  Variable[1].Type = SelectIdent.Type;

  IF (EQ (SelectIdent.Scope, NoEnv),
  message (ERROR, "selection applied to non record type", 
           0, COORDREF));
END;

SYMBOL SelectIdent INHERITS 
        IdUseScopeProp, ChkIdUse, IdentOcc,
        TypedUseId, ChkTypedUseId, PrtType
END;

This macro is attached to a product file.

The last symbol computation combines several roles to solve the record selection analysis task: A SelectIdent is an identifier occurrence (IdentOcc), which is bound in an explicitly determined scope (IdUseScopeProp). It is checked whether such a binding is found (ChkIdUse). With respect to type analysis, a SelectIdent is an occurrence of a typed object identifier (TypedUseId, ChkTypedUseId, PrtType).


Previous Chapter Next Chapter Table of Contents