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/(?:<=|>=|<|>lt|gt|le|ge)/,
qr/&/,
qr/(?:\||\^)/,
qr/&&/,
qr/(?:\|\||\/\/)/,
qr/(not)/,
qr/(and)/,
qr/(or|xor)/
];
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;
}
|