#!/user/bin/perl use strict; use warnings; use Parse::RecDescent; my $parser = new Parse::RecDescent (q( { my $operators = { '+' => sub { my $i = shift @_; $i += $_ for @_; return $i }, '-' => sub { my $i = shift @_; $i -= $_ for @_; return $i }, '*' => sub { my $i = shift @_; $i *= $_ for @_; return $i }, '/' => sub { my $i = shift @_; $i /= $_ for @_; return $i }, }; } line: paren /^\Z/ { $item[1] } paren: '(' op arg arg(s) ')' { $operators->{$item[2]}->($item[3], @{$item[4]}) } op: '+' | '-' | '*' | '/' arg: paren | /^[+-]?(?:\d+|\d*\.\d+)/ )); my $task = "(+3 4(*2 7(+1 -1))(/6 2))"; my $calc = $parser->line($task) || die "Syntax error in $task\n"; print $calc, $/;