PLACE
spec
solutions
PHP

RPN Calculator in PHP

As PHP borrows abundantly its tools for working with regular expressions from Perl, and as the calculator implementation in the latter language relies heavily on regexes, it makes sense to do the same job in PHP in a way similar to Perl's.

The implementation is meant to run in PHP's command-line mode. Although not embedded in HTML, the program needs its <?php and ?> tagging around the code so that the inside gets interpreted – any non-tagged text would have been simply echoed.

The program reads lines of text until it sees end of input (feof(STDIN)). Possible leading and trailing blanks are stripped off a line s so that it can be checked whether s is actually empty. If it is not, triples of the kind number-number-operator are repeatedly replaced in s by the result of the corresponding operation. Evaluation is ensured by the e option put at the end of the regex in the call of preg_replace. When there are no more such triples, s must have been reduced to a single number (and possibly blank characters around it). That final result is printed, after transforming it into a ‘canonical’ representation by means of floatval. If s's content happens to be not the correct one, an error message appears instead of result.

The four basic regexes defined at the start of the program, as well as the composed ones that are given as arguments to preg_replace and preg_match, and also the use of the special variables $1, $2 and $3 are identical to the regexes and the variables in the Perl implementation: please see there for some more details.

<?php
$pre = '(?:^|\s+)';
$post = '(?:\s+|$)';
$num = '([+-]?(?:\.\d+|\d+(?:\.\d*)?))';
$op = '([-+*\/])';
while (!feof(STDIN)) {
  $s = trim(fgets(STDIN));
  if ($s=='') continue;
  do {
    $s = preg_replace("/$pre$num\\s+$num\\s+$op$post/e",
                      "' '.($1 $3 $2).' '", $s, -1, $n);
  } while ($n);
  echo (preg_match("/^\\s*$num\\s*$/",$s) ? floatval($s) : 'error') . "\n";
}
?>

boykobbatgmaildotcom