use strict;
use warnings;
use feature 'say';

my $number   = '[+-/$]?(?:\.\d+|\d+(?:\.\d*)?)';
my $operator = '[-+*/^]';

my @tests = ('1 2 + 3 4 + ^ 5 6 + ^', '3 4 2 * 1 5 - 2 3 ^ ^ / +');

for (@tests) {
    my(@elems,$n);
    $n = -1;
    while (
        s/
            \s* (?<left>$number)   
            \s+ (?<right>$number)  
            \s+ (?<op>$operator)   
            (?:\s+|$)              
         /
            ' '.('$'.++$n).' '     
         /ex) {
            $elems[$n] = "($+{left}$+{op}$+{right})"  
         }
    while (
        s/ (\$)(\d+)    
         / $elems[$2]   
         /ex
        ) { say }       
    say '=>' . substr($_,2,-2)."\n";
}