$term = '((1 + 2) * (2 -1) + 7 / 5) + (2 * 3) + 5'; printf("TERM : $term\n"); $term =~ s/\s+//g; $idx = 1; #-----------------------------------------------------------------------------# sub evalSubTerm { my($op1, $op, $op2) = @_; if ( $op eq '*' ) { return($op1 * $op2); } elsif ( $op eq '/' ) { return($op1 / $op2); } elsif ( $op eq '+' ) { return($op1 + $op2); } else { return($op1 - $op2); } } #-----------------------------------------------------------------------------# sub resolveOps { my($op) = @_; for $subTerm ( values(%subTerms) ) { while ( ($subTerm =~ s!^(.*?[+-].*?)(T?\d+(?:\.\d*)?${op}T?\d+(?:\.\d*)?)(.*?)$!$1T$idx$3!) || ($subTerm =~ s!^(.*?)(T?\d+(?:\.\d*)?${op}T?\d+(?:\.\d*)?)(.*?[+-].*?)$!$1T$idx$3!) ) { $subTerms{"T$idx"} = $2; $idx++; } } } #-----------------------------------------------------------------------------# sub rearrangeTerms { my($subTerm, $value) = @_; my($tmpSubTerm, $retVal); for $tmpSubTerm ( keys(%subTerms) ) { $subTerms{$tmpSubTerm} =~ s!$subTerm!$value!g; } $retVal = $subTerms{$subTerm}; delete($subTerms{$subTerm}); return($retVal); } #-----------------------------------------------------------------------------# sub resolveTerms { my($subTerm, $retVal); my($modified) = 0; while ( scalar(%subTerms) >= 1 ) { for $subTerm ( keys(%subTerms) ) { if ( $subTerms{$subTerm} =~ m(^(\d+(?:\.\d*)?)([+\-\*/])(\d+(?:\.\d*)?)$) ) { $subTerms{$subTerm} = evalSubTerm($1, $2, $3); $retVal = rearrangeTerms($subTerm, $subTerms{$subTerm}); } } } return($retVal); } #-----------------------------------------------------------------------------# while ( $term =~ s/^(.*?)\(([^\(\)]+)\)(.*?)$/$1T$idx$3/ ) { $subTerms{"T$idx"} = $2; $idx++; } $subTerms{"T0"} = $term; for $op ( ('\*', '/', '\+', '-') ) { resolveOps($op) }; printf("RESULT: %s\n", resolveTerms());