Code Generation

The translation is approached as a particular case of tree decoration. Each node is decorated with a new attribute - trans - that will held the translation for such node. To compute it, we must define transformations for each of the types in the AST:
translation = t_num t_var t_op t_neg
             t_assign t_list t_print;

Some of these transformations are straightforward:

t_num: NUM 
  => { $NUM->{tr} = $NUM->{attr} }
t_op:  /TIMES|PLUS|DIV|MINUS/:b($x, $y)
  => {
    my $op = $Op{ref($b)};
    $b->{tr} = "$b->{reg} = $x->{reg}"
                   ." $op $y->{reg}";
  }
To keep track of the involved variables a hash is used as a rudimentary symbol table:
{ our %s; }
t_assign: ASSIGN($v, $e) => {
  $s{$v->{attr}} = "num";
  $ASSIGN->{tr} = "$v->{reg} = $e->{reg}"
}
The translation of the root node (EXPS) consists of concatenating the translations of its children:
{
  sub cat_trans {
    my $t = shift;

    my $tr = "";
    for ($t->children) {
      (ref($_) =~ m{NUM|VAR|TERMINAL})
        or $tr .= cat_trans($_)."\n"
    }
    $tr .= $t->{tr} ;
  }
}

t_list: EXPS(@S)
  => {
    $EXPS->{tr} = "";
    my @tr = map { cat_trans($_) } @S;
    $EXPS->{tr} =
      reduce { "$a\n$b" } @tr if @tr;
  }
The treeregexp @S matches the children of the EXPS node. The associated lexical variable @S contains the references to the nodes that matched.

The method bud9of Parse::Eyapp::Node nodes makes a bootom up traversing of the AST applying to the node being visited the only one transformation that matches10. After the call

$t->bud(our @translation);
the attribute $t->{trans} contains a translation to PIR for the whole tree.



Procesadores de Lenguaje 2007-03-01