trans that will held
the translation for such node.
To compute it, we define a translation transformation
t_class for each type of node class in the AST:
translation = t_num t_var t_op t_neg t_assign t_list t_print;
Some of these transformations are straightforward.
The translation of a NUM node is its value:
t_num: NUM => { $NUM->{tr} = $NUM->{attr} }
The translation of a binary operation node $b
is to apply the associated
binary operator $op to the registers $x->{reg}
and $y->{reg} where
the operands were stored and store it in the register
$b->{reg} associated with the node:
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 former rule says that the translation of an
ASSIGN node consists in assigning the contents
of the register assigned to the expression subtree
to the register assigned to the left hand side.
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 bud8of Parse::Eyapp::Node
nodes makes a bootom up traversing
of the AST applying to the node being visited the only one transformation that
matches9.
After the call
$t->bud(our @translation);the attribute
$t->{trans} contains
a translation to PIR for the whole tree.
Procesadores de Lenguajes 2010-01-31