zippovich2 / expressions-parser
Used shunting-yard algorithm to parse any expressions and RPN(Reverse Polish Notations) to execute it.
v1.0.1
2021-05-13 08:00 UTC
Requires
- php: >=7.3
Requires (Dev)
- friendsofphp/php-cs-fixer: ^2.18
- phpunit/phpunit: ^9.5
README
Used shunting-yard algorithm to convert any expressions to RPN(Reverse Polish Notations) and process it.
Installation
composer require zippovich2/expressions-parser
Predefined parsers
Arithmetical expressions parser
use Zippovich2\ExpressionsParser\Parser\ArithmeticalParser; $parser = new ArithmeticalParser(); // 45 $parser->eval('2 + (3^3) + 8 * (3 - 1)'); // 3.0001220703125 $parser->eval('3 + 4 * 2 / (1 - 5) ^ 2 ^ 3'); // 58 $parser->eval('58+(max(1, 2, 3)/3)');
Logical expressions parser
use Zippovich2\ExpressionsParser\Parser\LogicalParser; $parser = new LogicalParser(); // true $parser->eval('true || false'); // false $parser->eval('true && false'); // true $parser->eval('true xor false'); // false $parser->eval('true xor true');
Extending
use Zippovich2\ExpressionsParser\Parser\LogicalParser; use Zippovich2\ExpressionsParser\OperatorFactory; $parser = new LogicalParser(); $parser->addOperator(OperatorFactory::rightAssociative('**', function($a, $b){ return $a ** $b; }, 5)); $parser->addOperator(OperatorFactory::func('if', function($condition, $if, $else){ return $condition ? $if : $else; })); $parser->addOperator(OperatorFactory::constant('e', M_E)); // false $res = $parser->eval('if(2 < 1, true, false)'); // true $res = $parser->eval('if(2 > 1, true, false)'); // 16 $res = $parser->eval('2**4'); // 3.718281828459 $res = $parser->eval('e+1');
Custom parser
use Zippovich2\ExpressionsParser\Parser; use Zippovich2\ExpressionsParser\OperatorsList; use Zippovich2\ExpressionsParser\OperatorFactory; $operators = new OperatorsList(); $operators->add(OperatorFactory::leftAssociative('AND', function ($a, $b){ return $a && $b; })); $parser = new Parser($operators); // false $parser->eval('1 AND 0'); // true $parser->eval('1 AND 0');
Operators
Types
Operator::TYPE_LEFT_ASSOCIATIVE
- left associative.Operator::TYPE_RIGHT_ASSOCIATIVE
- right associative.Operator::TYPE_FUNCTION
- function.Operator::TYPE_LEFT_ASSOCIATIVE
- constant.
Reserved names
An operator cannot be created using the characters (
and )
because it is used for groups
and ,
because it is used for separating function parameters.
Callbacks
You can provide callback for each operator or create global callback to handle all operators.
use Zippovich2\ExpressionsParser\Parser; use Zippovich2\ExpressionsParser\OperatorsList; use Zippovich2\ExpressionsParser\OperatorFactory; $operators = new OperatorsList(); $operators->add(OperatorFactory::leftAssociative('AND', function ($a, $b){ return $a && $b; })); $operators->add(OperatorFactory::leftAssociative('OR')); $defaultCallback = function ($operator, ...$parameters){ switch ($operator){ case 'OR': return $parameters[0] || $parameters[1]; } throw new \LogicException('This code should not be reached.'); }; $parser = new Parser($operators); // true $parser->eval('1 AND 0 OR 1', $defaultCallback); // false $parser->eval('1 AND 0 OR 0', $defaultCallback); /** * @throws \LogicException because no callback was provided for "OR" operator. */ $parser->eval('1 AND 0 OR 0');