

La comprobación de tipos se hace mediante una visita
ascendente del AST: primero se comprueban y computan los tipos de los hijos
del nodo aplicándole las reglas del sistema de tipos que hemos implantado usando
transformaciones árbol. Despúes pasamos a computar el tipo del nodo.
Para la visita usamos el método bud
(por bottom-up decorator13.2)
de Parse::Eyapp::Node.
La llamada $t->bud(@typecheck) hace
que se visite cada uno de los nodos de $t en orden
bottom-up. Para cada nodo se busca una transformación árbol
en la lista @typecheck que se pueda aplicar.
Tan pronto como se encuentra una se aplica y se procede
con el siguiente nodo.
pl@nereida:~/doc/casiano/PLBOOK/PLBOOK/code/Simple-Types/lib/Simple$ \
sed -ne '/^sub compile/,/^}/p' Types.eyp | cat -n
1 sub compile {
2 my($self)=shift;
3
4 my ($t);
5
6 $self->YYData->{INPUT} = $_[0];
7
8 $t = $self->YYParse( yylex => \&_Lexer, yyerror => \&_Error,
9 #yydebug => 0x1F
10 );
11
12 # Scope Analysis: Block Hierarchy
13 our $blocks;
14 my @blocks = $blocks->m($t);
15 $_->node->{fatherblock} = $_->father->{node} for (@blocks[1..$#blocks]);
16
17 # Scope Analysis: Return-Function
18 our $retscope; # retscope: /FUNCTION|RETURN/
19 my @returns = $retscope->m($t);
20 for (@returns) {
21 my $node = $_->node;
22 if (ref($node) eq 'RETURN') {
23 my $function = $_->father->node;
24 $node->{function} = $function;
25 $node->{t} = $function->{t}->child(1);
26 }
27 }
28
29 # Type checking
30 set_types($t); # Init basic types
31
32 my @typecheck = ( # Check typing transformations for
33 our $inum, # - Numerical constantss
34 our $charconstant, # - Character constants
35 our $bin, # - Binary Operations
36 our $arrays, # - Arrays
37 our $assign, # - Assignments
38 our $control, # - Flow control sentences
39 our $functioncall, # - Function calls
40 our $statements, # - Those nodes with void type
41 # (STATEMENTS, PROGRAM, etc.)
42 our $returntype, # - Return
43 );
44
45 $t->bud(@typecheck);
46
47 # The type checking for trees RETURN exp is made
48 # in adifferent way. Just for fun
49 #our $bind_ret2function;
50 #my @FUNCTIONS = $bind_ret2function->m($t);
51
52 return $t;
53 }
La llamada a la subrutina set_types($t) tiene por
objeto establecer la comunicación entre el programa árbol en Trans.trg
y el compilador en Types.eyp. La subrutina se encuentra
en el código de apoyo en el programa árbol:
pl@nereida:~/doc/casiano/PLBOOK/PLBOOK/code/Simple-Types/lib/Simple$ \
sed -ne '17,62p' Trans.trg | cat -n
1 {
2
3 my $types; # reference to the hash containing the type table
4 my ($INT, $CHAR, $VOID);
5
6 sub type_error {
7 my $msg = shift;
8 my $line = shift;
9 die "Type Error at line $line: $msg\n"
10 }
11
12 sub set_types {
13 my $root = shift;
14 $types = $root->{types};
15 $INT = $types->{INT};
16 $CHAR = $types->{CHAR};
17 $VOID = $types->{VOID};
18 }
19
20 sub char2int {
.. ................;
31 }
32
33 sub int2char {
.. ................;
44 }
45
46 }
La subrutina set_types inicializa la variable léxica $types que referencia
a la tabla de tipos: No olvide que estamos en el fichero Trans.trg separado del
que contiene las restantes fases de análisis léxico, sintáctico y de ámbito.
Además la rutina inicia las referencias $INT, $CHAR
y $VOID que serán los árboles/hoja que representen
a los tipos básicos. Siguiendo el clásico texto del Dragón de Aho, Hopcroft y Ullman
[9] introducimos el tipo VOID para asociarlo a aquellos objetos que
no tienen tipo (sentencias, etc.).

