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 bud
9of 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.