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

Next Chapter Table of Contents


Tree Grammar Preconditions

Names are usually represented by identifier terminals. Their notation is determined by a scanner specification. The grammar has one (or several) terminals representing identifiers, e.g. Ident, as in the running example. The encoding of a particular identifier as computed by a scanner processor is available in contexts where an identifier terminal occurs.

Identifiers occur in different contexts: Defining and applied occurrences, or different kinds of identifiers (variables, labels, etc.) may be distinguished. Usually the concrete syntax is designed first, and the different computational roles of identifiers are incrementally developed during the design of the .lido specification. Hence, it is recommended NOT to make the distinction in the concrete syntax. It should have the terminal Ident in any context. It is rather recommended to distinguish them by LIDO RULEs.

Our running example has the concrete productions

   ObjDecl:        TypeDenoter Ident.
   TypeDenoter:    Ident.
   Variable:       Ident.
We distinguish the different roles of identifiers by introducing new symbol names in the corresponding LIDO RULEs:

   RULE: ObjDecl     ::= TypeDenoter DefIdent END;
   RULE: TypeDenoter ::= TypeUseIdent END;
   RULE: Variable    ::= UseIdent END;
Furthermore, we have to add the necessary chain RULEs:
   RULE: DefIdent     ::= Ident END;
   RULE: UseIdent     ::= Ident END;
   RULE: TypeUseIdent ::= Ident END;

The name analysis modules require that identifier occurrences are represented by nonterminals, like DefIdent, UseIdent, TypeUseIdent as in the example. Each of these symbols has to have an attribute named Sym of type int representing the identifier encoding. A specification using these modules has to contain suitable computations of the Sym attributes. For our example they may be specified like:

   ATTR Sym: int SYNT;
   SYMBOL IdentOcc COMPUTE SYNT.Sym = TERM; END;

   SYMBOL DefIdent     INHERITS IdentOcc END;
   SYMBOL UseIdent     INHERITS IdentOcc END;
   SYMBOL TypeUseIdent INHERITS IdentOcc END;

If your language does not syntactically distinguish between defining and applied identifier occurrences, i.e. objects are introduced by using their name, the above distinction is not necessary. You just introduce DefIdent symbols for all occurrences.

Your grammar should have a symbol representing a phrase that contains all (defining and applied) occurrences of a name space. It is usually the root of the whole grammar, e.g. in the running example the symbol Program.

If your language has hierarchically nested ranges defining boundaries for the scope of definitions, the abstract syntax should have one or several symbols, e.g. Range, Block, Routine, each representing a range of a name space. If the language does not have nested ranges for definitions you don't need such symbols.


Next Chapter Table of Contents