Looking and your code and algorithm description, I got the same impressions as MidLifeXis: the algorithm is simple (yet limited), correct, but slow. This is a classic problem that computer science students meet many times during their classes, each time using a different algorithm / approach to solve it, and the fellow monks already provided you many pointers (CPAN could be another).

Implementation wise, I'm sorry to say that yours looks like a mechanical line-to-line translation from that other language. Here are a few suggestions:

Finally, here's a possible rewrite of your code:

#!/usr/bin/perl use strict; use warnings; { my $OP = { # operator => weight '+' => 4, '-' => 4, '*' => 7, '/' => 7, '**' => 8, '(' => 9, ')' => 9, }; my $depth_bonus = 1 + ( sort { $b <=> $a } values %{$OP} )[0]; my $ops_re = join q{|}, map { quotemeta } sort { length $b <=> length $a } keys %{$OP}; sub eval_expr { my $expr = "@_"; my @terms; my $depth = 0; while ( $expr =~ s{^ \s* ( \d+ | $ops_re ) }{}xo ) { if ( $1 eq '(' ) { $depth++; } elsif ( $1 eq ')' ) { $depth--; } else { push @terms, [ $1, exists $OP->{$1} ? $OP->{$1} + $depth * $depth +_bonus : 0 ]; } } while ( @terms > 1 ) { my ($op_idx) = sort { $terms[$b]->[1] <=> $terms[$a]->[1] } 0 .. $#term +s; my @elems = map { $_->[0] } @terms[ $op_idx - 1 .. $op_idx + + 1 ]; splice @terms, $op_idx - 1, 3, [ eval("@elems"), 0 ]; } return $terms[0]->[0]; } } for ( '3 - ( 4 + 5 )', '1 + 2 * 3', '( 1 + 2 ) * 3', ' 5 ** 2 - 2 ** 3', ) { my $evaled = eval("$_"); my $expred = eval_expr($_); printf "%40s = %-20s %s\n", $_, $expred, $evaled; }
As you may notice, while it preserves you original approach / algorithm / didacticism, it also tries to be more flexible and simplifies some steps, observing that operands do not need priority/weight. 'HTH

In reply to Re: a timid approach to parsing arithmetic expressions in perl by AltBlue
in thread a timid approach to parsing arithmetic expressions in perl by spx2

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.