Arithmetic expression solver PHP library

Overview

arithmexp

An arithmetic expression solver

Usage

$operators = OperatorRegistry::default();

$expression = new ArithmeticExpression($operators, "4 - 3 + 5");
$value = $expression->solve(); // 6

$expression = new ArithmeticExpression($operators, "4 - x + y");
$value = $expression->solve(["x" => 3, "y" => 5]); // 6
$value = $expression->solve(["x" => 4, "y" => 5]); // 5
Comments
  • Support for `6/2(1+2)` expression

    Support for `6/2(1+2)` expression

    6/2(1+2) i think this expression should be parsed as 6/[2(1+2)] instead of throwing an error.

    * Sorry I couldn't find a suitable title for this issue

    > https://youtu.be/URcUvFIUIhQ (may be related)
    enhancement wontfix 
    opened by NhanAZ 1
  • Improve sub-expression comparison in Operator Strength Reduction

    Improve sub-expression comparison in Operator Strength Reduction

    opened by Muqsit 1
  • Cannot negate variables in expression directly

    Cannot negate variables in expression directly

    Trying to parse the expression 4 * -var throws the following error

    ArithmeticExpressionException: "No right-side operand found for 'T_OPERATOR' at '*' [3:3] while parsing '4 * -var'"
    

    The expressions 4 * (-var) and -var * 4 work as expected, however.

    bug ast 
    opened by Muqsit 1
  • Unary operations must have lower precedence than exponentiation

    Unary operations must have lower precedence than exponentiation

    Currently, all unary operations are given a higher precedence than all binary operations. Following PHP's operator precedence, the exponentiation binary operation must have a higher precedence than the unary operations. Due to conflicting precedence, the result of the expression -3 ** 2 does not match with the result in PHP:

    var_dump($parser->parse("-3 ** 2")->evaluate());
    // int(9)
    // is evaluated as: (-3) ** 2
    
    var_dump(-3 ** 2);
    // int(-9)
    // is evaluated as: -(3 ** 2)
    
    bug 
    opened by Muqsit 0
  • Add support for various forms of brackets

    Add support for various forms of brackets

    I think it should parse curly braces and square brackets from the input. These brackets make the expression easier to read and write. An example a + {[b - (c / d)] * 3} better a + ((b - (c / d)) * 3}

    enhancement 
    opened by NhanAZ 0
  • Result of subtraction optimization produces wrong value

    Result of subtraction optimization produces wrong value

    Optimization on the expression (x - 0) - (0 - y) should result in x + y, not x - y.

    https://github.com/Muqsit/arithmexp/blob/328895eee6e9a637f586b42a040cd673ae52a255/tests/muqsit/arithmexp/OptimizerTest.php#L281

    bug good first issue 
    opened by sylvrs 0
  • Replace recursive method calls with an iterative approach

    Replace recursive method calls with an iterative approach

    Recursion has an overhead on memory, can result in stack overflow for deeply nested expressions, and makes stack traces spammy (see below). The parser performs recursive method calls when traversing the token tree in various places such as here, here, here, and here.

    muqsit@*********:~/arithmexp/tests$ php test3.php "x + min(mt_rand(1, 3), mt_rand(2, mt_rand(3, 4, 5)), 7) * y"
    
    Fatal error: Uncaught muqsit\arithmexp\ParseException: Cannot resolve function call at "mt_rand(3, 4, 5)" (34:50) in "x + min(mt_rand(1, 3), mt_rand(2, mt_rand(3, 4, 5)), 7) * y": Too many parameters supplied to function call: Expected 2 parameters, got 3 parameters
     | x + min(mt_rand(1, 3), mt_rand(2, mt_rand(3, 4, 5)), 7) * y
     |                                   ^^^^^^^^^^^^^^^^ in /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/ParseException.php:32
    Stack trace:
    #0 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/ParseException.php(144): muqsit\arithmexp\ParseException::generateWithHighlightedSubstring(Object(muqsit\arithmexp\ParseException))
    #1 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(352): muqsit\arithmexp\ParseException::unresolvableFcallTooManyParams('x + min(mt_rand...', Object(muqsit\arithmexp\token\FunctionCallToken), Object(muqsit\arithmexp\function\FunctionInfo), 3)
    #2 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(283): muqsit\arithmexp\Parser->transformFunctionCallTokens('x + min(mt_rand...', Array)
    #3 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(283): muqsit\arithmexp\Parser->transformFunctionCallTokens('x + min(mt_rand...', Array)
    #4 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(283): muqsit\arithmexp\Parser->transformFunctionCallTokens('x + min(mt_rand...', Array)
    #5 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(283): muqsit\arithmexp\Parser->transformFunctionCallTokens('x + min(mt_rand...', Array)
    #6 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(283): muqsit\arithmexp\Parser->transformFunctionCallTokens('x + min(mt_rand...', Array)
    #7 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(283): muqsit\arithmexp\Parser->transformFunctionCallTokens('x + min(mt_rand...', Array)
    #8 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(283): muqsit\arithmexp\Parser->transformFunctionCallTokens('x + min(mt_rand...', Array)
    #9 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(143): muqsit\arithmexp\Parser->transformFunctionCallTokens('x + min(mt_rand...', Array)
    #10 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(97): muqsit\arithmexp\Parser->processTokens('x + min(mt_rand...', Array)
    #11 /home/muqsit/arithmexp/tests/test3.php(13): muqsit\arithmexp\Parser->parseExpression('x + min(mt_rand...')
    #12 {main}
      thrown in /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/ParseException.php on line 32
    
    
    enhancement help wanted 
    opened by Muqsit 0
  • Properly implement operator precedence

    Properly implement operator precedence

    At the moment, operator precedence is implemented by performing a simple lookup on a sorted array of operators. https://github.com/Muqsit/arithmexp/blob/ebcb0ad67c636d7f9b7addaba786168b8c664e87/src/muqsit/arithmexp/token/BinaryOperatorToken.php#L10-L17

    This means there are no operators with equal precedence in the library at the moment. Associativity (left-associativity vs right-associativity) is what should be the determining factor for precedence when it comes to operators with equal precedence.

    help wanted 
    opened by Muqsit 0
  • Confusion of - and + operators with negative and positive numbers

    Confusion of - and + operators with negative and positive numbers

    Since "-" and "+" are binary operators, two operands need to be explicitly declared on either sides of the operator, such as 3 + 5. This limits expressions from declaring negative or positive numbers without explicitly adding a zero on the missing side.

    6 - -1
    // ArithmeticExpressionException: "No right-side operand found for 'T_OPERATOR' at '-' [5:5] while parsing '6 - -1'"
    
    6 - (0-1)
    // 7
    
    help wanted lexing 
    opened by Muqsit 0
  • Optimizer does not account for INF and NAN

    Optimizer does not account for INF and NAN

    Description

    Operator Strength Reduction optimizer directly substitutes a sub-expression x - x with 0, not accounting for INF or NAN values being supplied to x (inf - inf and nan - nan must produce nan). Other affected cases include 0 * inf returning 0 instead of NAN, and sqrt(-1) / sqrt(-1) getting substituted for 1 despite sqrt(-1) === NAN (NAN / NAN === NAN).

    As variable resolution occurs during evaluation, x - x cannot be resolved during parsing although 1 - 1 and inf - inf can. One way to address this would be to resolve operations between numeric literal operands during parsing and implement a mechanism to toggle optimizations that disregard INF and NAN (like GCC's FloatingPointMath flags).

    Workarounds

    1. Filter out operator strength reduction optimization from ExpressionOptimizerRegistry
      $parser = Parser::createDefault();
      
      $optimizations = new ExpressionOptimizerRegistry();
      foreach($parser->getExpressionOptimizerRegistry()->getRegistered() as $identifier => $value){
      	if(!($value instanceof OperatorStrengthReductionExpressionOptimizer)){
      		$optimizations->register($identifier, $value);
      	}
      }
      
      $parser = new Parser(
      	$parser->getBinaryOperatorRegistry(),
      	$parser->getUnaryOperatorRegistry(),
      	$parser->getConstantRegistry(),
      	$parser->getFunctionRegistry(),
      	$optimizations,
      	$parser->getScanner()
      );
      
    2. Disable optimizations altogether — $parser = Parser::createUnoptimized();
    bug 
    opened by Muqsit 0
  • Support for factorial

    Support for factorial

    Something like this

    $parser = Parser::createDefault();
    $expression = $parser->parse("2! + 3!");
    var_dump($expression->evaluate()); // int(8)
    

    or

    $parser = Parser::createDefault();
    $expression = $parser->parse("fact(2) + fact(3)");
    // https://www.php.net/manual/en/function.gmp-fact.php
    var_dump($expression->evaluate()); // int(8)
    

    2! + 3! instead of 1*2 + 1*2*3

    enhancement 
    opened by NhanAZ 0
  • Add support for Solver Equations

    Add support for Solver Equations

    Supports solving equations like:

    • Simul Equation
      • 2 Unknowns
      • 3 Unknowns
      • 4 Unknowns
      • n Unknowns
    • Polynomial
      • $ax^2 + bx + c$
      • $ax^3 + bx^2 + cx + d$
      • $ax^4 + bx^3 + cx^2 + dx + e$
      • $a_n x^n + a_{n-1}x + a_{n-2}x^{n-2} + \dots + a_1x^1 + a_0$
    • Equation (Find values of variable)

    Maybe this feature is not suitable for your library but it would be nice if it was added. I found a similar library for this feature but it seems to be no longer maintained. https://github.com/Samshal/Equation-Solver

    enhancement help wanted 
    opened by NhanAZ 0
  • Add support for arbitrary-length numbers

    Add support for arbitrary-length numbers

    $parser = Parser::createDefault();
    
    $expression = $parser->parse("111111111111111111111111111111111111111111111111111111111111111111111111111");
    var_dump($expression->evaluate()); // int(9223372036854775807)
    
    $expression = $parser->parse("111111111111111111111111111111111111111111111");
    var_dump($expression->evaluate()); // int(9223372036854775807)
    
    $expression = $parser->parse("99999999999999999999999");
    var_dump($expression->evaluate()); // int(9223372036854775807)
    
    $expression = $parser->parse("9999999999999999999999999999999999");
    var_dump($expression->evaluate()); // int(9223372036854775807)
    
    enhancement help wanted 
    opened by NhanAZ 8
  • Comparison Operators

    Comparison Operators

    Something like:

    $parser = Parser::createDefault();
    
    $expression = $parser->parse("2 + 3 > 5");
    var_dump($expression->evaluate()); // bool(false)
    
    $expression = $parser->parse("2 + 3 => 5");
    var_dump($expression->evaluate()); // bool(true)
    

    Comparison Operators: https://www.php.net/manual/en/language.operators.comparison.php

    enhancement good first issue 
    opened by NhanAZ 2
Releases(0.1.29)
  • 0.1.29(Nov 15, 2022)

    • Fixed unary positive operation resulting in negation since v0.1.28 (80ceccfd92c6575b419297874cf6d0606b1406a7)
    • Further optimized expression evaluation (6d0c7998d2003eec6d3b540b80630ce44ac8ae1b)
    • Implemented modulo operator strength reduction for identity property ((a % n) % n => a % n) (bca7b1719618c4fd316cb5bc380069ea4616a747, 98535479ae9a4b6e74dbe448d33ab74bf77b8657)
    • Removed functions rand() and getrandmax() (these functions exist in PHP only for backward compatibility) (ce8dfb3dc46e2cc7ee30a13febb7e802994301d9)
    • mt_rand() now accepts zero parameters (in addition to accepting two parameters) (8194bf3c279e4699df95457996dc482e6bc9a9bd, f73be6140e42007a4ed9fe7d423dfc113ebab758)
    • Implemented mode constants for round() (HALF_UP, HALF_DOWN, HALF_EVEN, HALF_ODD) (c21ce74f35dde4b3af8fe383cf9d48fa68198882, 90c0f5df57f4c53ccd39514898541d1926ece790)
    • Renamed FunctionRegistry::register() to FunctionRegistry::register() (ad076413b326ded9bd3a5f43ff83544d941aa9f5)
    • Renamed ConstantRegistry::register() to ConstantRegistry::registerLabel() (1b0d2d575c0a636476eb85ccbce7fd029e6b289a)
    • Moved FunctionRegistry::registerMacro() to MacroRegistry::registerFunction() (0d0889fdcaefb5d1e443c8aee1b492dcaa087f75)
    • Implemented object-like macros that can be registered by calling MacroRegistry::registerObject() (34e5ad71836b74a686130acfd2a720abcce01679)
    Source code(tar.gz)
    Source code(zip)
  • 0.1.28(Nov 12, 2022)

    • Improved performance of evaluating operator tokens (de91e05748623ed2923ab2c3a5b70a1dc4054d4d, 998ec6a8ac09e7104fcb76436f602d1facda7817, 5b40d3cfe95e8967b72910bdf43021c0bcacb720, 4acfe1d2160fe172d448b260d6397ca0ff08c5cf, 3a7790930cb1ed904fa78344d73efae5e061130a)
    Source code(tar.gz)
    Source code(zip)
  • 0.1.27(Nov 6, 2022)

  • 0.1.26(Nov 4, 2022)

    • Introduced Parser::getOperatorManager() (4ff725f3b958a2372668729195193438880b73e1)
      • Replaced Parser::getBinaryOperatorRegistry() with Parser::getOperatorManager()->getBinaryRegistry()
      • Replaced Parser::getUnaryOperatorRegistry() with Parser::getOperatorManager()->getUnaryRegistry()
    • Fixed a few cases where optimizers did not account for INF and NAN (#16) (1ef49eb44e1a0723e42a771cc680f2afc15396f6, db1df91b986e023dfdba1bf002da0b2410ddaefa, 03440abd8d9cede1a22ce6cf90991a293934a6ed, b9dd31e9bb23faace4203493b85f6dc7c5f9aaca, 3c9b8a081c947c136204a18685f27cf58e6d9fe7, 14442caf91dcfe540c595ac3be06af554d7b2c77, 082ccf3bfde0aff653fb0819bf3b9728a309d538)
    • Fixed operator precedence of unary operators being greater than exponentiation (#17) (4ff725f3b958a2372668729195193438880b73e1)
    • Fixed division by zero with zero 0 / 0 returning int(0) with optimizations (167297038be3529e90d554abe6027fbbf6be18ef)
    • Function properties (commutativity and determinism) are governed by function flags instead of boolean properties (3e348456d66092051cc8066ccd7028b9baaaf579)
      • See newer examples on the wiki on registering custom binary operators, unary operators, and functions
    • Implemented idempotent functions (bd0860973098224497d2dc731f8eeef3f8f6f4a2)
    Source code(tar.gz)
    Source code(zip)
  • 0.1.25(Oct 23, 2022)

    • Fixed a bug that allowed using square brackets and curly brackets to enclose function call argument list (aa716293eaafdf20eec9577cba441265dc6aea1c)
    • Errored subexpressions are no longer highlighted if the subexpression is the expression itself (65290a666f2e3a9e9a7c6f533faf1e81aa60684d)
    • Improved performance of operator strength reduction by precomputing numeric literals within operands (32cf8f42b1dd3bf56b1107062bf776f2e87b0b22)
    Source code(tar.gz)
    Source code(zip)
  • 0.1.24(Oct 20, 2022)

    • Added support for various forms of brackets (square brackets [] and curly brackets {} are now considered as valid in expressions) (#13, thanks @NhanAZ!)
    Source code(tar.gz)
    Source code(zip)
  • 0.1.23(Oct 18, 2022)

    • Registered functions for a parser can now be accessed via FunctionRegistry::register() (d003841c373b003f3fa2c2e15f25dad23e321460)
    • Improved operator strength reduction performance over addition with negative operands (2bf277e4799a8e09b677449d9be2f02345647bda, ff81320defe4e49a15b2913425aae07f4d9a185c)
    • Improved operator strength reduction performance over subtraction with negative operands (da2168549de8bde9741f5093e7616a5e6f021a6b, ff81320defe4e49a15b2913425aae07f4d9a185c)
    • Fixed a critical bug where operator strength reduction over subtraction with lvalue=0 resulted in rvalue instead of -rvalue (#11, 4f4aaea17a350385b2637fed9d5eaf645f2de745, 029e47001543ab3928ad19662d2b0de90fcb03a4) (thanks @sylvrs!)
    Source code(tar.gz)
    Source code(zip)
  • 0.1.22(Oct 14, 2022)

    • Implemented quotient rule of exponents (a ** m / a ** n =a ** (m - n)`) in strength reduction optimization (757e7b05ea6cf2e4fa5517f293db92a32f485cdc)
    • Fixed a bug in the optimizer that caused function calls in expressions to be optimized by name (889145820f06279865e97d1041473e2c1ca7e49c)
    • Fixed a bug in the optimizer that failed to parse expressions containing nested function calls with zero parameters (such as min(pi())) (4d334144960ca02c92aaa0c82ce8a04c774f93e6)
    Source code(tar.gz)
    Source code(zip)
  • 0.1.21(Oct 12, 2022)

    • Expression::getVariables() has been renamed to Expression::findVariables()
    • Fixed a bug where exponentiation of 2 with itself resulted expression executing indefinitely
    Source code(tar.gz)
    Source code(zip)
  • 0.1.20(Oct 10, 2022)

    • Fixed a bug causing operator strength reduction to not work on function calls with >2 arguments
    • Use of same unary operator consecutively is now valid (#10, thanks @NhanAZ!)
    • Operator strength reduction now optimizes unary positive and unary negative operations
    Source code(tar.gz)
    Source code(zip)
  • 0.1.19(Oct 9, 2022)

    • Improved strength reduction over division operations
    • Added a "commutative" property to functions
    • min and max no longer throw an error when only 1 parameter is supplied
    • Parser now attempts to catch division-by-zero during parsing
    Source code(tar.gz)
    Source code(zip)
  • 0.1.18(Oct 8, 2022)

  • 0.1.17(Oct 7, 2022)

    • BinaryOperators can now be checked for commutativity through BinaryOperator::isCommutative()
    • Improved Operator Strength Reduction optimization by accounting for commutativity of binary operations (#8, thanks @sylvrs!)
    Source code(tar.gz)
    Source code(zip)
  • 0.1.16(Oct 6, 2022)

    • OSR now optimizes expressions such as x - x to 0
    • OSR now optimizes 1 ** x to 1
    • Fixed parse errors arising from OSR not correctly building token tree
    • Removed Parser::parseRawExpression()
      • Parser::createUnoptimized()->parse() may be used instead
    Source code(tar.gz)
    Source code(zip)
  • 0.1.15(Oct 4, 2022)

  • 0.1.14(Oct 2, 2022)

  • 0.1.13(Oct 2, 2022)

    • ParseException now highlights the problematic substring within the expression along with displaying the exception message
      • Before
        Fatal error: Uncaught muqsit\arithmexp\ParseException: Cannot resolve function call at "mt_rand(3, 4, 5)" (34:50) in "x + min(mt_rand(1, 3), mt_rand(2, mt_rand(3, 4, 5)), 7) * y": Too many parameters supplied to function call: Expected 2 parameters, got 3 parameters
        
      • After
        Fatal error: Uncaught muqsit\arithmexp\ParseException: Cannot resolve function call at "mt_rand(3, 4, 5)" (34:50) in "x + min(mt_rand(1, 3), mt_rand(2, mt_rand(3, 4, 5)), 7) * y": Too many parameters supplied to function call: Expected 2 parameters, got 3 parameters
         | x + min(mt_rand(1, 3), mt_rand(2, mt_rand(3, 4, 5)), 7) * y
         |                                   ^^^^^^^^^^^^^^^^ 
        
    • Stack traces of errors arising from the parser are now more concise
      • Before
        muqsit@*********:~/arithmexp/tests$ php test3.php "x + min(mt_rand(1, 3), mt_rand(2, mt_rand(3, 4, 5)), 7) * y"
        
        Fatal error: Uncaught muqsit\arithmexp\ParseException: Cannot resolve function call at "mt_rand(3, 4, 5)" (34:50) in "x + min(mt_rand(1, 3), mt_rand(2, mt_rand(3, 4, 5)), 7) * y": Too many parameters supplied to function call: Expected 2 parameters, got 3 parameters
         | x + min(mt_rand(1, 3), mt_rand(2, mt_rand(3, 4, 5)), 7) * y
         |                                   ^^^^^^^^^^^^^^^^ in /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/ParseException.php:32
        Stack trace:
        #0 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/ParseException.php(144): muqsit\arithmexp\ParseException::generateWithHighlightedSubstring(Object(muqsit\arithmexp\ParseException))
        #1 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(352): muqsit\arithmexp\ParseException::unresolvableFcallTooManyParams('x + min(mt_rand...', Object(muqsit\arithmexp\token\FunctionCallToken), Object(muqsit\arithmexp\function\FunctionInfo), 3)
        #2 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(283): muqsit\arithmexp\Parser->transformFunctionCallTokens('x + min(mt_rand...', Array)
        #3 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(283): muqsit\arithmexp\Parser->transformFunctionCallTokens('x + min(mt_rand...', Array)
        #4 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(283): muqsit\arithmexp\Parser->transformFunctionCallTokens('x + min(mt_rand...', Array)
        #5 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(283): muqsit\arithmexp\Parser->transformFunctionCallTokens('x + min(mt_rand...', Array)
        #6 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(283): muqsit\arithmexp\Parser->transformFunctionCallTokens('x + min(mt_rand...', Array)
        #7 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(283): muqsit\arithmexp\Parser->transformFunctionCallTokens('x + min(mt_rand...', Array)
        #8 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(283): muqsit\arithmexp\Parser->transformFunctionCallTokens('x + min(mt_rand...', Array)
        #9 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(143): muqsit\arithmexp\Parser->transformFunctionCallTokens('x + min(mt_rand...', Array)
        #10 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(97): muqsit\arithmexp\Parser->processTokens('x + min(mt_rand...', Array)
        #11 /home/muqsit/arithmexp/tests/test3.php(13): muqsit\arithmexp\Parser->parseExpression('x + min(mt_rand...')
        #12 {main}
          thrown in /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/ParseException.php on line 32
        
      • After
        muqsit@*********:~/arithmexp/tests$ php test3.php "x + min(mt_rand(1, 3), mt_rand(2, mt_rand(3, 4, 5)), 7) * y"
        
        Fatal error: Uncaught muqsit\arithmexp\ParseException: Cannot resolve function call at "mt_rand(3, 4, 5)" (34:50) in "x + min(mt_rand(1, 3), mt_rand(2, mt_rand(3, 4, 5)), 7) * y": Too many parameters supplied to function call: Expected 2 parameters, got 3 parameters
         | x + min(mt_rand(1, 3), mt_rand(2, mt_rand(3, 4, 5)), 7) * y
         |                                   ^^^^^^^^^^^^^^^^ in /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/ParseException.php:32
        Stack trace:
        #0 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/ParseException.php(144): muqsit\arithmexp\ParseException::generateWithHighlightedSubstring(Object(muqsit\arithmexp\ParseException))
        #1 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(337): muqsit\arithmexp\ParseException::unresolvableFcallTooManyParams('x + min(mt_rand...', Object(muqsit\arithmexp\token\FunctionCallToken), Object(muqsit\arithmexp\function\FunctionInfo), 3)
        #2 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(143): muqsit\arithmexp\Parser->transformFunctionCallTokens('x + min(mt_rand...', Array)
        #3 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(97): muqsit\arithmexp\Parser->processTokens('x + min(mt_rand...', Array)
        #4 /home/muqsit/arithmexp/tests/test3.php(13): muqsit\arithmexp\Parser->parseExpression('x + min(mt_rand...')
        #5 {main}
          thrown in /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/ParseException.php on line 32
        
    Source code(tar.gz)
    Source code(zip)
  • 0.1.12(Oct 2, 2022)

    • BinaryOperatorRegistry no longer ends up in an invalid state when an InvalidArgumentException thrown by BinaryOperatorRegistry::register() is handled
    • Numbers with multiple decimal points (such as 3..2, 3.2.1, etc.) are no longer parsed as numeric literals
    • Function call token's "end pos" is now at closing parenthesis of its argument list
      • Parse exceptions arising from function calls are more comprehensible
        // before
        > tan(x) + tan(y) tan(z) ** tan(w)
        Unexpected Function Call token encountered at "tan" (16:19) in "tan(x) + tan(y) tan(z) ** tan(w)"
        
        // after
        > tan(x) + tan(y) tan(z) ** tan(w)
        Unexpected Function Call token encountered at "tan(z)" (16:22) in "tan(x) + tan(y) tan(z) ** tan(w)"
        
    Source code(tar.gz)
    Source code(zip)
  • 0.1.11(Oct 1, 2022)

    • Parser now throws a ParseException when encountering tokens that cannot be resolved to expression tokens
      • This fixes several cases where unexpected tokens are encountered (such as , outside fcall) where a RuntimeException would have instead been thrown with the message "Don't know how to convert * token"
    Source code(tar.gz)
    Source code(zip)
  • 0.1.10(Oct 1, 2022)

    • Add a method to observe changes to BinaryOperatorRegistry and UnaryOperatorRegistry
    • Fix operator token builders not updating operator list for runtime registrations
    • Fix a bug causing nested unary tokens to be improperly grouped
    Source code(tar.gz)
    Source code(zip)
  • 0.1.9(Sep 30, 2022)

    • Parser now throws ParseException when secluded tokens are encountered (such as 2 3 + 4 or tan(x) tan(y)) instead of silently ignoring
    • Fix ParseException being incorrectly thrown for specific nested binary operations
    • Fix operators in function arguments incorrectly throwing a ParseException
    Source code(tar.gz)
    Source code(zip)
  • 0.1.8(Sep 30, 2022)

  • 0.1.6(Sep 29, 2022)

  • 0.1.5(Sep 29, 2022)

    • ParseException is now thrown when a missing opening/closing parenthesis is encountered
    • ParseException is now thrown when no lvalue or rvalue is supplied for a binary operator
    • ParseException is now thrown when no rvalue is supplied for a unary operator
    • ParseException is now thrown when the supplied expression is empty
    • ParseException now extends Exception
      • This change lets IDEs hint developers to catch ParseException when Parser::parse() is invoked
    Source code(tar.gz)
    Source code(zip)
  • 0.1.3(Sep 29, 2022)

    • Added support for deterministic functions (see wiki)
    • Segments of the expression (or the expression as a whole) are now precalculated to reduce runtime computation
    Source code(tar.gz)
    Source code(zip)
  • 0.1.2(Sep 28, 2022)

  • 0.1.0(Sep 28, 2022)

Owner
Muqsit Rayyan
Block or Report
Muqsit Rayyan
PHP Expression Language

PHP Expression Language The purpose of this library is to provide a common base for an PHP Expression Language. This is not really a creative library

KitanoLabs 32 Oct 21, 2022
Best regular expression for gmail

best regular expression for gmail Gmail Regular expression with all details (not start with dot,number , is it possible to use multiple dot but not in

null 3 Feb 2, 2022
Dobren Dragojević 6 Jun 11, 2023
Easy to use utility functions for everyday PHP projects. This is a port of the Lodash JS library to PHP

Lodash-PHP Lodash-PHP is a port of the Lodash JS library to PHP. It is a set of easy to use utility functions for everyday PHP projects. Lodash-PHP tr

Lodash PHP 474 Dec 31, 2022
PHP Text Analysis is a library for performing Information Retrieval (IR) and Natural Language Processing (NLP) tasks using the PHP language

php-text-analysis PHP Text Analysis is a library for performing Information Retrieval (IR) and Natural Language Processing (NLP) tasks using the PHP l

null 464 Dec 28, 2022
php-echarts is a php library for the echarts 5.0.

php-echarts 一款支持Apache EChart5.0+图表的php开发库 优先ThinkPHP5/6的开发及测试。 Apache EChart5.0已经最新发布,在视觉效果、动画效果和大数据展示方面已经远超之前的版本; 故不考虑EChart5.0之前版本的兼容问题;建议直接尝试5.0+

youyiio 5 Aug 15, 2022
Minimalist PHP frame for Core-Library, for Developing PHP application that gives you the full control of your application.

LazyPHP lightweight Pre-Made Frame for Core-library Install Run the below command in your terminal $ composer create-project ryzen/lazyphp my-first-pr

Ry-Zen 7 Aug 21, 2022
Gettext is a PHP (^7.2) library to import/export/edit gettext from PO, MO, PHP, JS files, etc.

Gettext Note: this is the documentation of the new 5.x version. Go to 4.x branch if you're looking for the old 4.x version Created by Oscar Otero http

Gettext 651 Dec 29, 2022
Columnar analytics for PHP - a pure PHP library to read and write simple columnar files in a performant way.

Columnar Analytics (in pure PHP) On GitHub: https://github.com/envoymediagroup/columna About the project What does it do? This library allows you to w

Envoy Media Group 2 Sep 26, 2022
:date: The VObject library for PHP allows you to easily parse and manipulate iCalendar and vCard objects

sabre/vobject The VObject library allows you to easily parse and manipulate iCalendar and vCard objects using PHP. The goal of the VObject library is

sabre.io 532 Dec 25, 2022
Small convention based CQRS library for PHP

LiteCQRS for PHP Small naming-convention based CQRS library for PHP (loosely based on LiteCQRS for C#) that relies on the MessageBus, Command, EventSo

Benjamin Eberlei 560 Nov 20, 2022
Experimental library for forking PHP

Spork: PHP on a Fork <?php $manager = new Spork\ProcessManager(); $manager->fork(function() { // do something in another process! return 'Hel

Kris Wallsmith 588 Nov 20, 2022
Collection pipeline library for PHP

Knapsack Collection pipeline library for PHP Knapsack is a collection library for PHP >= 5.6 that implements most of the sequence operations proposed

Dušan Kasan 540 Dec 17, 2022
A PHP library to play with the Raspberry PI's GPIO pins

php-gpio php-gpio is a simple PHP library to play with the Raspberry PI's GPIO pins. It provides simple tools such as reading & writing to pins. [UPDA

Ronan Guilloux 266 Oct 17, 2022
PHP library for dealing with European VAT

ibericode/vat This is a simple PHP library to help you deal with Europe's VAT rules. Fetch VAT rates for any EU member state using ibericode/vat-rates

ibericode 389 Dec 31, 2022
iOS passbook library for PHP 5.4+

PHP PASSBOOK LIBRARY What is Passbook? Passbook is an application in iOS that allows users to store coupons, boarding passes, event tickets, store car

Eymen Gunay 256 Nov 17, 2022
Sslurp is a simple library which aims to make properly dealing with SSL in PHP suck less.

Sslurp v1.0 by Evan Coury Introduction Dealing with SSL properly in PHP is a pain in the ass and completely insecure by default. Sslurp aims to make i

Evan Coury 65 Oct 14, 2022
A framework agnostic PHP library to build chat bots

BotMan If you want to learn how to create reusable PHP packages yourself, take a look at my upcoming PHP Package Development video course. About BotMa

BotMan 5.8k Jan 1, 2023
Lock library to provide serialized execution of PHP code.

Requirements | Installation | Usage | License and authors | Donations php-lock/lock This library helps executing critical code in concurrent situation

null 875 Jan 7, 2023