Parsing/RPN calculator algorithm: Difference between revisions

Content added Content deleted
(→‎{{header|Perl}}: same logic, more readable)
Line 3,276: Line 3,276:


=={{header|Perl}}==
=={{header|Perl}}==
<lang Perl>
<lang perl>use strict;
use warnings;
# RPN calculator
use feature 'say';
#

# Nigel Galloway April 2nd., 2012
my $number = '[+-]?(?:\.\d+|\d+(?:\.\d*)?)';
#
$WSb = '(?:^|\s+)';
my $operator = '[-+*/^]';

$WSa = '(?:\s+|$)';
my @tests = ('3 4 2 * 1 5 - 2 3 ^ ^ / +');
$num = '([+-/]?(?:\.\d+|\d+(?:\.\d*)?))';

$op = '([-+*/^])';
sub myE {
for (@tests) {
while (
my $a = '('.$1.')'.$3.'('.$2.')';
s/ \s* ((?<left>$number)) # 1st operand
$a =~ s/\^/**/;
\s+ ((?<right>$number)) # 2nd operand
return eval($a);
\s+ ((?<op>$operator)) # operator
(?:\s+|$) # more to parse, or done?
/
' '.evaluate().' ' # substitute results of evaluation
/ex
) {}
say;
}
}

while (<>) {
sub evaluate {
while (s/$WSb$num\s+$num\s+$op$WSa/' '.myE().' '/e) {}
(my $a = "($+{left})$+{op}($+{right})") =~ s/\^/**/;
print ($_, "\n");
say $a;
}
eval $a;
</lang>
}</lang>
Produces:
{{out}}
<pre>
<pre>(4)*(2)
>rpnC.pl
(1)-(5)
3 4 2 * 1 5 - 2 3 ^ ^ / +
(2)**(3)
3.0001220703125
(-4)**(8)
</pre>
(8)/(65536)
(3)+(0.0001220703125)
3.0001220703125</pre>


=={{header|Perl 6}}==
=={{header|Perl 6}}==