#!/usr/bin/perl use strict; use warnings; my %operator = ( '+' => sub { my $i = 0; $i += $_ for @_; $i; }, '-' => sub { my $i = shift @_; @_ or return -$i; $i -= $_ for @_; $i; }, '*' => sub { my $i = 1; $i *= $_ for @_; $i; }, '/' => sub { my $i = shift @_; @_ or return 1/$i; $i /= $_ for @_; $i; }, ); my $ops = join '' => keys %operator; my $task = "( + 3 4 ( * 2 7 ( + 1 1 ) ) ( / 6 2 ) )"; 1 while $task =~ s/\(\s*([$ops])((?:\s*\d+)+)\s*\)/ local $_ = $2; $operator{$1}->(split); /e; print $task;