The examples used in this document can be found in the file examples/typechecking/Simple-Types-XXX.tar.gz. This distribution contains the front-end of a compiler (lexical analysis, syntax analysis, scope analysis and type checking) for a small subset of the C language. The language has characters, integers, arrays and functions. Here is a small example:

To take advantage of Parse::Eyapp::Scope, the compiler writer must mark at the appropriate time (for example a new block or new subroutine for identifier scope analysis, a new loop for loop scope analysis, etc.) the beginning of a new scope calling the method begin_scope. For example, the following code deals with the declaration of functions

From that point on, any ocurring instance of an object (for example, variables in expressions for identifier scope analysis, breaks and continues for loop scope analysis, etc.) must be declared calling the method scope_instance. For example, the following rules deal with the use of of variables and functions inside expressions:

The programmer must also mark the end of the current scope at the appropriate time. After the processing of the block following a function declaration an identifier scope has finished and we call end_scope:

There are three ways of calling $scope->end_scope. The first one is for Scope Analysis Problems where a symbol table is needed (for example in identifier scope analysis and label scope analysis and there is a Parse::Eyapp::Node node that owns the scope.

An entry $x->{SCOPE_NAME} is built that will reference $definition_node.

An entry $x->{ENTRY_NAME} is built. That entry references $symboltable{$x->key} (to have a faster access from the instance to the attributes of the object). The instantiated nodes must have a $x->key method which provides the entry for the node in the symbol table:

For each aditional arguments attr#k an entry $x->{attr#k} will be built. That entry references $symboltable{$x->key}{attr#k}. Therefore the entry for $x in the symbol table must already have a field named attr#k. If the hash referenced by $symboltable{$x->key} does not have a key attr#k no reference is built.

In a list context $scope>end_scope returns two references. The first one is a reference to a list of node instantiated that weren't defined in the current scope. The second is a reference to a list of nodes that were defined in this scope. In a scalar context returns the first of these two. An instance $x is defined if, and only if, exists $symboltable{$_->key}.

For each ocurring instance of an object $x that occurred since the last call to begin_scope the call to

$scope->end_scope(\%symboltable, 'attr1', 'attr2', ... )

decorates the ocurring instance$x with several attributes:

An entry $x->{ENTRY_NAME} is built. That entry references $symboltable{$x->key} (to have a faster access from the instance to the attributes of the object). The instantiated nodes must have a $x->key method which provides the entry for the node in the symbol table.

For each aditional arguments attr#k an entry $x->{attr#k} will be built. That entry references $symboltable{$x->key}{attr#k}. Therefore the entry for $x in the symbol table must already have a field named attr#k. If the hash referenced by $symboltable{$x->key} does not have a key attr#k no reference is built.

Some scope analysis problems do not require the existence of a symbol table (for instance, the problem of associating a RETURN node with the FUNCTION that encloses it). For such kind of problems $scope>end_scope provides a second form of call.

The second way to call $scope>end_scope is

$declared = $scopemanager->end_scope($definition_node);

The only argument is the reference to the node that controls/defines the scope. The method returns a reference to the declared nodes. Any node instanced with scope_instance since the last call to begin_scope is considered declared.

The scope node $definition_node is decorated with an attribute with name the value of the attribute SCOPE_NAME of the scope manager $scopemanager. The value of the attribute is the anonymous list of references to the instances declared in the scope of $definition_node (i.e. the same list referenced by $declared).

The scope instances in @$declared are decorated with an attribute with name the value of the attribute SCOPE_NAME of the scope manager. The value is a reference to the scope node $definition_node.

Parse::Eyapp::Scope->new returns a scope management object. The scope mapping function is implemented by Parse::Eyapp::Scope through a set of attributes that are added to the nodes involved in the scope analysis. The names of these attributes can be specified using the parameters of Parse::Eyapp::Scope->new. The arguments of new are:

SCOPE_NAME is the name chosen for the attribute of the node instance which will held the reference to the definition node. If not specified it will take the value "scope".

ENTRY_NAME is the name of the attribute of the node instance which will held the reference to the symbol table entry. By default takes the value "entry".

SCOPE_DEPTH is the name for an attribute of the definition node. Optional. If not specified it will not be defined.

This work has been supported by CEE (FEDER) and the Spanish Ministry of Educacion y Ciencia through Plan Nacional I+D+I number TIN2005-08818-C04-04 (ULL::OPLINK project http://www.oplink.ull.es/). Support from Gobierno de Canarias was through GC02210601 (Grupos Consolidados). The University of La Laguna has also supported my work in many ways and for many years.

A large percentage of code is verbatim taken from Parse::Yapp 1.05. The author of Parse::Yapp is Francois Desarmenien.

I wish to thank Francois Desarmenien for his Parse::Yapp module, to my students at La Laguna and to the Perl Community. Thanks to the people who have contributed to improve the module (see "CONTRIBUTORS" in Parse::Eyapp). Thanks to Larry Wall for giving us Perl. Special thanks to Juana.