In fact, I find this pretty interesting:
#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper;
$Data::Dumper::Terse=1;
my $precedence_perlop=[
qr/(?:\/\*\%x)/,
qr/(?:\+\.)/,
qr/(?:<=>=<>ltgtlege)/,
qr/&/,
qr/(?:\\^)/,
qr/&&/,
qr/(?:\\\/\/)/,
qr/(not)/,
qr/(and)/,
qr/(orxor)/
];
sub parse{
my ($regex,$input)=@_;
$input=~s/\s//g;
for(reverse @$regex){
if($input=~m/(.+)($_)(.+)/){
my ($before,$op,$after,$node)=($1,$2,$3);
$node>{$op}=[parse($regex,$before),parse($regex,$after)];
return $node;
}
}
return $input;
}
sub evaluate {
my $tree = shift;
return $tree unless ref $tree;
foreach my $op ( keys %{$tree} ) {
my @terms = map { evaluate($_) } @{ $tree>{$op} };
my $result;
eval "\$result = $terms[0] $op $terms[1]";
return undef if $@;
return $result;
}
}
while(<>){
my $tree = parse($precedence_perlop,$_);
print Dumper($tree);
my $ev = evaluate( $tree );
print "Evaluate to: " . $ev . "\n"
if defined $ev;
}
