$z $x $y #### $z = $x + $y #### { my $twig = new XML::Twig ( %constructor ) ; $twig->parse($elt->next_elt->sprint); } #### #!/usr/local/bin/perl use Data::Dumper; use XML::Twig; ++$|; our $pmode = 1; my $pstring; sub pt { my (@string) = @_; for (@string) { if ($pmode) { print $_; } else { $pstring .= $_; } } } # print expression - no semicolon at end sub pe { pt $_[0] } # print statement - semicolon at end sub ps { pt "$_[0];\n"; } # print statement demux - distribute 1 fish to each of the masses sub ps_dmux { my ($fish, @masses) = @_; map { ps "$fish $_" } @masses; } # print statement with masses as a parenthesized arguement sub ps_pare { my ($fish, @masses) = @_; ps sprintf "$fish (%s)", join ',', @masses; } my %constructor = ( StartTagHandlers => { scope => sub { print "{" }, perl => sub { my $T = $_[1]->att("binary"); printf "#!%s\n", $T }, }, TwigHandlers => { scope => sub { print "}" }, use => sub { my @p = split /\s+/, $_[1]->text; ps_dmux $_[1]->gi, @p }, my => sub { my @p = split /\s+/, $_[1]->text; ps_pare $_[1]->gi, @p }, print => sub { my @p = split /\s+/, $_[1]->text; ps_pare $_[1]->gi, @p }, add => sub { my @p = split /\s+/, $_[1]->text; warn " [add pmode: $pmode]\ "; pe join '+', @p }, set => sub { my $elt = $_[1]; my @children = $elt->children; if (@children == 1) { ps sprintf "%s = %s", split /\s+/, $elt->text } else { # children == 2 or more { local $pmode; pt $elt->next_elt->text, " = "; $elt = $elt->next_elt; warn " [else pmode : $pmode ] "; my $twig = new XML::Twig ( %constructor ) ; $twig->parse($elt->next_elt->sprint); warn " [else pmode 2 : $pmode ] "; } warn " [ non-local pmode: $pmode ]"; pt $pstring; $pstring = ''; } } } ); my $twig = new XML::Twig ( %constructor ) ; my $file = shift or die "usage: $0 perxml.xml"; $twig->parsefile($file); #### strict warnings diagnostics $x $y $z $x 111 $y 554 $z $x $y $z