#!/usr/bin/perl -w use strict; use Parse::Eyapp; use Parse::Eyapp::Treeregexp; my $grammar = q{ %right '=' %left '-' '+' %left '*' '/' %left NEG %tree %{ use Tail2; # See file examples/Tail2.pm in the distribution %} %% block: exp <%name BLOCK + ';'> { $_[1] } ; exp: %name NUM NUM | %name WHILE 'while' exp '{' block '}' | %name VAR VAR | %name ASSIGN VAR '=' exp | %name PLUS exp '+' exp | %name MINUS exp '-' exp | %name TIMES exp '*' exp | %name DIV exp '/' exp | %name UMINUS '-' exp %prec NEG | '(' exp ')' { $_[2] } /* Let us simplify a bit the tree */ ; %% }; # end grammar sub TERMINAL::info { $_[0]{attr} } $Parse::Eyapp::Node::INDENT = 2; our (@all,$moveinvariant, $condition, $assign, $before, $after); Parse::Eyapp->new_grammar( input=>$grammar, classname=>'Rule6', firstline=>7, ); my $parser = Rule6->new(); my $program = "a =1000; c = 1; while (a) { c = c*a; b = 5; a = a-1 }\n"; my $t = $parser->Run(\$program); my @output = split /\n/, $t->str; my $p = Parse::Eyapp::Treeregexp->new( STRING => q{ moveinvariant: BLOCK( @prests, WHILE(VAR($b), BLOCK(@a, ASSIGN($x, NUM($e)), @c)), @possts ) => { my $assign = $ASSIGN; $BLOCK[1]->delete($ASSIGN); $BLOCK[0]->insert_before($WHILE, $assign); } }, ); $p->generate(); $moveinvariant->s($t); my @output2 = split /\n/, $t->str; my ($node1, $node2); format STDOUT_TOP = PROGRAM ------------------------------------------------------- @|||||||||||||||||||||||||||||||||||||||||||||||||||||| $program ------------------------------------------------------- Before | After ---------------------------|--------------------------- . format STDOUT = @<<<<<<<<<<<<<<<<<<<<<<<<<<@|@<<<<<<<<<<<<<<<<<<<<<<<<< $node1, '|',$node2 . for (1..$#output) { $node1 = $output[$_]; $node2 = $output2[$_]; write; }