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.).