The example of PEAR-FSM is very difficult to use, with a space input and strange input method, now I would like to change an improved version.
<?php/* rpneasy.php author:mx 2014-12-04 Using FSM to achieve simple arithmetic, not support first multiplication after adding minus */require_once ' fsm.php ';//operand 1 encountered numeric function Buildsmallnumber ($symbol, & $payload) {array _push ($payload, $symbol);} Operand 1 continuously encounters the number function Buildbignumber ($symbol, & $payload) {$n = Array_pop ($payload); $n = $n. $symbol; $n = (int) $n; Array_push ($payload, $n);} Encountered operator function Buildop ($symbol, & $payload) {Array_push ($payload, $symbol);} Operand 2 encountered digital function BuildSmallNumber2 ($symbol, & $payload) {Array_push ($payload, $symbol);} Operand 2 continuously encounters the number function BuildBigNumber2 ($symbol, & $payload) {$n = Array_pop ($payload); $n = $n. $symbol; $n = (int) $n; Array_push ($payload, $n);} function Endbuildnumber ($symbol, & $payload)//{//$n = Array_pop ($payload); Array_push ($payload, (int) $n),//}function doequaltemp ($symbol, & $payload) {/////////////////////For the calculation/operation of objects 2 $ar = Array_pop ($payload);//Operator $s = array_pop ($payload);//Operation object 1 $al = Array_pop ($payload); if ($s = = ' + ') {Array_push ($payload, $al + $ar); } elseif ($s = = '-') {Array_push ($payload, $al-$ar); } elseif ($s = = ' * ') {Array_push ($payload, $al * $ar); } elseif ($s = = '/') {Array_push ($payload, $al/$ar); }//Latest operator Array_push ($payload, $symbol);} function Doequal ($symbol, & $payload) {if (count ($payload) >2) {//Action object 2$ar = Array_pop ($payload);//Operator $s = Array_ Pop ($payload);//Operand 1$al = Array_pop ($payload), if ($s = = ' + ') {Array_push ($payload, $al + $ar),} elseif ($s = = '-') {array _push ($payload, $al-$ar);} ElseIf ($s = = ' * ') {Array_push ($payload, $al * $ar);} elseif ($s = = '/') {Array_push ($payload, $al/$ar);}} echo Array_pop ($payload). "\ n";} function Error ($symbol, $payload) {echo "This does not compute: $symbol \ n";} $stack = Array (), $FSM = new FSM (' init ', $stack); $FSM->setdefaulttransition (' init ', ' Error ');//Status: The start read must be a number. Numbers can be followed by numbers or subtraction or =, operators must be followed by numbers. $FSM->addtransitionany (' init ', ' init '), $FSM->addtransitions (range (0,9), ' init ', ' INPUT1 ', ' Buildsmallnumber '); $fsm->addtransitions (range (0),9), ' INPUT1 ', ' INPUT1 ', ' Buildbignumber '), $FSM->addtransitions (Array (' + ', '-', ' * ', '/'), ' INPUT1 ', ' OPERATE ', ' Buildop '); $fsm->addtransitions (Range (0,9), ' OPERATE ', ' INPUT2 ', ' BuildSmallNumber2 '); $FSM->addtransitions ( Range (0,9), ' INPUT2 ', ' INPUT2 ', ' BuildBigNumber2 '), $FSM->addtransitions (Array (' + ', '-', ' * ', '/'), ' INPUT2 ', ' OPERATE ', ' doequaltemp '); $FSM->addtransition (' = ', ' INPUT2 ', ' INIT ', ' doequal '); echo "expression:\n"; $stdin = fopen (' Php://stdin ', ' R '); $expression = RTrim (fgets ($stdin)); $symbols = Preg_split ('//', $expression,-1, Preg_split_no_ EMPTY); $fsm->processlist ($symbols);
Run the next PHP directory \rpneasy.php
Input 11+22-3+5 and so on, test success!
The main change in this example is that the original code is to maintain only the number of the stack, with a space as the input end delimiter, hit the symbol to start counting, so enter 3 4 + such format. Now to distinguish between Operation Object 1, operator, operand 2 (that is, corresponding to the original code in the Al,ar symbol of the left and right), the operator is also staged into the stack, you can support continuous uninterrupted tight computation expression.
However, this is the persistence from the left to the right of the smoothing calculation, if you want to first multiplication after the band or first add minus or multiplication, operators have priority?
[PHP play field] study on PEAR-FSM (iii) improving the arithmetic of PEAR-FSM