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

Name analysis according to scope rules

Previous Chapter Next Chapter Table of Contents


Predefined Identifiers

In most languages some identifiers are predefined, e.g. names for basic types or for constants like true and false. Their definitions are valid in any program as if they were bound in the outermost environment. The two modules PreDefine and PreDefId described here allow to easily introduce such predefinitions. They require that one of the basic scope rule modules (see Basic Scope Rules) is used.

Both modules PreDefine and PreDefId are to be instantiated to introduce a set of predefined entities in a name space.

The implementation of the modules use two functions which introduce a source identifier into the identifier table and establish a binding for it in some environment. These functions can be used directly for example in cases where predefinitions are to be established for other environments than the outermost one. Those functions are described below.

The PreDefine module is instantiated by

   $/Name/PreDefine.gnrc +instance=NAME +referto=IDENT :inst
The optional instance parameter characterizes the name space in which identifiers are to be predefined. The instance parameter has to be the same as that of the basic scope rule module instance used for that name space. Several instances of this module may address different name spaces.

The referto parameter specifies the symbol name used for identifier terminals in the grammar. The referto parameter must not be omitted.

If a grammar has several identifier terminal symbols predefinitions can be made using several instances of this module, if they belong to different name spaces.

The module provides two functions NAMEPreDefine and NAMEPreDefineSym which are called by the instance of the PreDefId module. NAMEPreDefineSym inserts a string into the identifier module to be used as an IDENT symbol. NAMEPreDefine additionally binds that symbol to a key in the root environment given by the global variable NAMERootEnv.

The predefined identifiers are to be described in a file as explained below. The name of that file has to be given as referto parameter of the instantiation of the PreDefId module:

   $/Name/PreDefId.gnrc +instance=NAME +referto=(FILENAME) :inst
The instance parameter has to be the same as that of the PreDefine instance. If this instantiation is contained in a .specs file and if the description file, say Predef.d is contained in the same directory, it may read
   $/Name/PreDefId.gnrc +referto=(Predef.d) :inst
This can also be used if the .specs file and Predef.d are contained in a .fw specification.

The description file contains a sequence of macro calls, one for each predefined identifier, e.g.

  PreDefKey ("int", intKey)
  PreDefKey ("real", realKey)
  PreDefSym ("external", externSym)
  PreDefSymKey ("fail", failSym, failKey)
  PreDefSymKeyBind ("write", writeSym, writeKey, writeBind)
The sequence should not contain anything else, because it is expanded in several contexts where different definitions of those macros are valid.

Each call of one of the macros establishes a predefinition for one identifier, and makes the result accessible via the supplied variable names. Usually not all of those variables are needed. Hence, the available macros differ in the combinations of those variables. We first explain the most general macro. The meanings of the other macros are deduced from it.

PreDefSymKeyBind ("xxx", sym, key, bind) encodes the character string xxx as an identifier, stores it in the identifier table, and stores the encoding in the int variable sym.

Note: The string need not obey the rules specified for the notation of IDENT symbols. That facility can be used if artifacts are predefined, which can not be referred to by a name in a program.

key is introduced as a PDL known key.

key is bound to sym in the environment NAMERootEnv. That binding is assigned to the Binding variable bind. The key, the identifier code, and the environment can be accessed from the Binding value (KeyOf, IdnOf, EnvOf).

The variables sym and bind and the known key key are defined, exported, and made accessible via a .HEAD.phi specification. The binding is established and the assignments are made in the initialization phase of the processor. Hence, the results can be used only after that phase, i.e. during all computations in the tree.

According to the above description the following macro call

  PreDefSymKeyBind ("write", writeSym, writeKey, writeBind)
creates the following variables to be defined and initialized as described:
  int writeSym;
  DefTableKey writeKey;
  Binding writeBind;

The other macros that are provided cause a subset of the effects described for PreDefSymKeyBind:

PreDefSymKey ("xxx", sym, key) As described above, except: The binding is established but not assigned to a variable.

PreDefKeyBind ("xxx", key, bind) As described above, except: The symbol is encoded and stored in the identifier table, but the encoding is not assigned to a variable.

PreDefKey ("xxx", key) As described above, except: Neither the symbol encoding nor the binding are stored in a variable.

PreDefBind ("xxx", bind) As described above, except: The symbol encoding is not stored in a variable. The key is created dynamically rather than as a known key. Both, symbol encoding and the key can be accessed via the stored Binding value.

PreDefSym ("xxx", sym) encodes the character string xxx as an identifier, stores it in the identifier table, and stores the encoding in the int variable sym. No binding is established.

The thus introduced variables and known keys may be used in .lido specifications; the known keys may be additionally used in any specification where PDL defined entities are available.

The described modules are based on a C module which provides the following two functions. They may be used directly to establish bindings in other environments than the outermost one, for example. In that case it is sufficient to use the module PreDefMod.specs. Then the modules PreDefine and PreDefId need not be instantiated, if the macros explained above are not used.

The two functions are:

void PreDefineSym (char *name, int code, int *sym)
The string name is encoded with the given syntax code. That is usually the code of the symbol used for identifier terminals in the grammar (cf. the referto parameter in the instantiation of the module PreDefine explained above). *sym is set to the symbol index.

void PreDefine (char *name, int code, int *sym, Environment env, DefTableKey key,Binding *bind)
The string name is encoded with the given syntax code which is bound to key in the given environment env. *sym is set to the symbol index. *bind is set to the created binding, if successful, otherwise to NoBinding.

In our running example we introduce predefined names for some basic types and for Boolean constants by the module instantiations

   $/Name/PreDefine.gnrc +referto=Ident :inst
   $/Name/PreDefId.gnrc +referto=(Predef.d):inst
The file Predef.d contains
  PreDefKey ("int", intKey)
  PreDefKey ("real", realKey)
  PreDefKey ("bool", boolKey)
  PreDefKey ("true", trueKey)
  PreDefKey ("false", falseKey)
Then key names like intKey can be used e.g. in computations for type checking (see Type Analysis of Type analysis tasks). In that case it is necessary to state that true and false are of type bool in a .pdl specification:
   trueKey -> TypeOf = {boolType};
   falseKey -> TypeOf = {boolType};
It associates the TypeOf property to the predefined objects.


Previous Chapter Next Chapter Table of Contents