From e8ede3d6a56fdef00f14de7ae8699ed4ca890712 Mon Sep 17 00:00:00 2001 From: Bruce Wells Date: Wed, 19 Dec 2018 16:07:24 -0500 Subject: Documentation fixes (#34) Fixing typos in and clarifying documentation. --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index c15dccb..39490a4 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,10 @@ A simple math expressions calculator * Built in support for +, -, *, / and power (^) operators plus () * Support for user defined operators * Support for user defined functions -* Unlimited varable name lengths -* String support, as function parameters or as evaluated by PHP +* Unlimited variable name lengths +* String support, as function parameters or as evaluated as a number by PHP * Exceptions on divide by zero, or treat as zero -* Unary Minus +* Unary Minus (e.g. -3) * Pi ($pi) and Euler's number ($e) support to 11 decimal places ## Install via Composer: @@ -121,7 +121,7 @@ $pi = 3.14159265359 $e = 2.71828182846 ``` -You can add own variable to executor: +You can add your own variables to executor: ```php $executor->setVars([ @@ -132,7 +132,7 @@ $executor->setVars([ echo $executor->execute("$var1 + $var2"); ``` ## Division By Zero Support: -By default, the result of division by zero is zero and no error is generated. You have the option to thow a \NXP\Exception\DivisionByZeroException by by calling setDivisionByZeroException. +By default, the result of division by zero is zero and no error is generated. You have the option to thow a \NXP\Exception\DivisionByZeroException by calling setDivisionByZeroException. ```php $executor->setDivisionByZeroException(); @@ -147,7 +147,7 @@ try { Negative numbers are supported via the unary minus operator, but need to have a space before the minus sign. `-1+ -3` is legal, while '`-1+-3` will produce an error due to the way the parser works. Positive numbers are not explicitly supported as unsigned numbers are assumed positive. ## String Support: -Expressions can contain double or single quoted strings that are evaluated the same way as PHP. You can also pass strings to functions. +Expressions can contain double or single quoted strings that are evaluated the same way as PHP evalutes strings as numbers. You can also pass strings to functions. ```php echo $executor->execute("1 + '2.5' * '.5' + myFunction('category')"); -- cgit v1.2.3 From 808593bacfe50cb25d2edfd814135172295a884c Mon Sep 17 00:00:00 2001 From: Timur Date: Thu, 10 Jan 2019 01:51:21 +0300 Subject: MathExecutor allow override default operators, functions and vars (#36) --- src/NXP/Classes/TokenFactory.php | 11 +++-- src/NXP/MathExecutor.php | 99 ++++++++++++++++++++++++++++------------ 2 files changed, 78 insertions(+), 32 deletions(-) diff --git a/src/NXP/Classes/TokenFactory.php b/src/NXP/Classes/TokenFactory.php index 6956f31..4ed55af 100644 --- a/src/NXP/Classes/TokenFactory.php +++ b/src/NXP/Classes/TokenFactory.php @@ -50,12 +50,17 @@ class TokenFactory /** * Add function - * @param string $name + * @param string $name * @param callable $function - * @param int $places + * @param int $places + * @throws \ReflectionException */ - public function addFunction($name, callable $function, $places = 1) + public function addFunction($name, callable $function, $places = null) { + if ($places === null) { + $reflector = new \ReflectionFunction($function); + $places = $reflector->getNumberOfParameters(); + } $this->functions[$name] = [$places, $function]; } diff --git a/src/NXP/MathExecutor.php b/src/NXP/MathExecutor.php index fbf6ab1..706f8af 100644 --- a/src/NXP/MathExecutor.php +++ b/src/NXP/MathExecutor.php @@ -53,35 +53,6 @@ class MathExecutor $this->addDefaults(); } - /** - * Set default operands and functions - */ - protected function addDefaults() - { - $this->tokenFactory = new TokenFactory(); - - $this->tokenFactory->addOperator('NXP\Classes\Token\TokenPlus'); - $this->tokenFactory->addOperator('NXP\Classes\Token\TokenMinus'); - $this->tokenFactory->addOperator('NXP\Classes\Token\TokenMultiply'); - $this->tokenFactory->addOperator('NXP\Classes\Token\TokenDivision'); - $this->tokenFactory->addOperator('NXP\Classes\Token\TokenDegree'); - - $this->tokenFactory->addFunction('sin', 'sin'); - $this->tokenFactory->addFunction('cos', 'cos'); - $this->tokenFactory->addFunction('tn', 'tan'); - $this->tokenFactory->addFunction('asin', 'asin'); - $this->tokenFactory->addFunction('acos', 'acos'); - $this->tokenFactory->addFunction('atn', 'atan'); - $this->tokenFactory->addFunction('min', 'min', 2); - $this->tokenFactory->addFunction('max', 'max', 2); - $this->tokenFactory->addFunction('avg', function($arg1, $arg2) { return ($arg1 + $arg2) / 2; }, 2); - - $this->setVars([ - 'pi' => 3.14159265359, - 'e' => 2.71828182846 - ]); - } - /** * Get all vars * @@ -262,4 +233,74 @@ class MathExecutor return $result; } + + /** + * Set default operands and functions + */ + protected function addDefaults() + { + $this->tokenFactory = new TokenFactory(); + + foreach ($this->defaultOperators() as $operatorClass) { + $this->tokenFactory->addOperator($operatorClass); + } + + foreach ($this->defaultFunctions() as $name => $callable) { + $this->tokenFactory->addFunction($name, $callable); + } + + $this->setVars($this->defaultVars()); + } + + protected function defaultOperators() + { + return [ + 'NXP\Classes\Token\TokenPlus', + 'NXP\Classes\Token\TokenMinus', + 'NXP\Classes\Token\TokenMultiply', + 'NXP\Classes\Token\TokenDivision', + 'NXP\Classes\Token\TokenDegree', + ]; + } + + protected function defaultFunctions() + { + return [ + 'sin' => function ($arg) { + return sin($arg); + }, + 'cos' => function ($arg) { + return cos($arg); + }, + 'tn' => function ($arg) { + return tan($arg); + }, + 'asin' => function ($arg) { + return asin($arg); + }, + 'acos' => function ($arg) { + return acos($arg); + }, + 'atn' => function ($arg) { + return atan($arg); + }, + 'min' => function ($arg1, $arg2) { + return min($arg1, $arg2); + }, + 'max' => function ($arg1, $arg2) { + return max($arg1, $arg2); + }, + 'avg' => function ($arg1, $arg2) { + return ($arg1 + $arg2) / 2; + }, + ]; + } + + protected function defaultVars() + { + return [ + 'pi' => 3.14159265359, + 'e' => 2.71828182846 + ]; + } } -- cgit v1.2.3 From 4c86b6fab82c50af4bd6449ec5fe39242d3ace74 Mon Sep 17 00:00:00 2001 From: Alexander Kiryukhin Date: Thu, 10 Jan 2019 21:23:20 +0300 Subject: Added simple coc (#37) * Added simple coc * Fix --- code-of-conduct.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 code-of-conduct.md diff --git a/code-of-conduct.md b/code-of-conduct.md new file mode 100644 index 0000000..83e0f4e --- /dev/null +++ b/code-of-conduct.md @@ -0,0 +1,9 @@ +# Code of conduct + +We don't care who you are IRL. Be professional and responsible. + +If you are a good person, we are happy for you. + +If you are an asshole to us, we will be assholes in relation to you. + +> Do to no one what you yourself dislike \ No newline at end of file -- cgit v1.2.3 From 13230631322675a6e07c4fde0f9c78626b336469 Mon Sep 17 00:00:00 2001 From: Bruce Wells Date: Thu, 10 Jan 2019 13:35:39 -0500 Subject: Replaceable operators (#38) * Updated from NeonXP/MathExecutor * Fixed function in () block issue * Fixing typos in and clarifying documentation. * Syncing from origin (#3) * Documentation fixes (#34) Fixing typos in and clarifying documentation. * MathExecutor allow override default operators, functions and vars (#36) * Allow for operators to be replaced based on regex expression --- README.md | 12 ++++++++++++ src/NXP/Classes/TokenFactory.php | 3 +-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 39490a4..6579a23 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ A simple math expressions calculator * Exceptions on divide by zero, or treat as zero * Unary Minus (e.g. -3) * Pi ($pi) and Euler's number ($e) support to 11 decimal places +* Easily extendable ## Install via Composer: Stable branch @@ -152,3 +153,14 @@ Expressions can contain double or single quoted strings that are evaluated the s ```php echo $executor->execute("1 + '2.5' * '.5' + myFunction('category')"); ``` + +## Extending MathExecutor +You can add operators, functions and variables with the public methods in MathExecutor, but if you need to do more serious modifications to base behaviours, the easiest way to extend MathExecutor is to redefine the following methods in your derived class: +* defaultOperators +* defaultFunctions +* defaultVars + +This will allow you to remove functions and operators if needed, or implement different types more simply. + +Also note that you can replace an existing default operator by adding a new operator with the same regular expression string. For example if you just need to redefine TokenPlus, you can just add a new operator with the same regex string, in this case '\+'. + diff --git a/src/NXP/Classes/TokenFactory.php b/src/NXP/Classes/TokenFactory.php index 4ed55af..778cb59 100644 --- a/src/NXP/Classes/TokenFactory.php +++ b/src/NXP/Classes/TokenFactory.php @@ -88,8 +88,7 @@ class TokenFactory throw new UnknownOperatorException($operatorClass); } - $this->operators[] = $operatorClass; - $this->operators = array_unique($this->operators); + $this->operators[$operatorClass::getRegex()] = $operatorClass; } /** -- cgit v1.2.3 From 790827ff45639b8a18485186ab0a31eb4263f119 Mon Sep 17 00:00:00 2001 From: Bruce Wells Date: Thu, 10 Jan 2019 13:53:34 -0500 Subject: Fix md typo (#39) * Updated from NeonXP/MathExecutor * Fixed function in () block issue * Fixing typos in and clarifying documentation. * Syncing from origin (#3) * Documentation fixes (#34) Fixing typos in and clarifying documentation. * MathExecutor allow override default operators, functions and vars (#36) * Syncing to origin (#4) * Documentation fixes (#34) Fixing typos in and clarifying documentation. * MathExecutor allow override default operators, functions and vars (#36) * Added simple coc (#37) * Added simple coc * Fix * Replaceable operators (#38) * Updated from NeonXP/MathExecutor * Fixed function in () block issue * Fixing typos in and clarifying documentation. * Syncing from origin (#3) * Documentation fixes (#34) Fixing typos in and clarifying documentation. * MathExecutor allow override default operators, functions and vars (#36) * Allow for operators to be replaced based on regex expression * \\ instead of \ --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 6579a23..95a772d 100644 --- a/README.md +++ b/README.md @@ -162,5 +162,4 @@ You can add operators, functions and variables with the public methods in MathEx This will allow you to remove functions and operators if needed, or implement different types more simply. -Also note that you can replace an existing default operator by adding a new operator with the same regular expression string. For example if you just need to redefine TokenPlus, you can just add a new operator with the same regex string, in this case '\+'. - +Also note that you can replace an existing default operator by adding a new operator with the same regular expression string. For example if you just need to redefine TokenPlus, you can just add a new operator with the same regex string, in this case '\\+'. -- cgit v1.2.3 From bf6204aea73441f222d5b9ebb828f9da9d6894ad Mon Sep 17 00:00:00 2001 From: Alexander Kiryukhin Date: Fri, 11 Jan 2019 02:15:26 +0300 Subject: Update README.md Some small fixes --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 95a772d..f411aa2 100644 --- a/README.md +++ b/README.md @@ -133,7 +133,7 @@ $executor->setVars([ echo $executor->execute("$var1 + $var2"); ``` ## Division By Zero Support: -By default, the result of division by zero is zero and no error is generated. You have the option to thow a \NXP\Exception\DivisionByZeroException by calling setDivisionByZeroException. +By default, the result of division by zero is zero and no error is generated. You have the option to throw a `\NXP\Exception\DivisionByZeroException` by calling `setDivisionByZeroException`. ```php $executor->setDivisionByZeroException(); @@ -145,7 +145,7 @@ try { ``` ## Unary Minus Operator: -Negative numbers are supported via the unary minus operator, but need to have a space before the minus sign. `-1+ -3` is legal, while '`-1+-3` will produce an error due to the way the parser works. Positive numbers are not explicitly supported as unsigned numbers are assumed positive. +Negative numbers are supported via the unary minus operator, but need to have a space before the minus sign. `-1+ -3` is legal, while `-1+-3` will produce an error due to the way the parser works. Positive numbers are not explicitly supported as unsigned numbers are assumed positive. ## String Support: Expressions can contain double or single quoted strings that are evaluated the same way as PHP evalutes strings as numbers. You can also pass strings to functions. -- cgit v1.2.3 From 76517641f79e8f0e4e5f3b620c731bf5c095df17 Mon Sep 17 00:00:00 2001 From: Alexander Kiryukhin Date: Fri, 11 Jan 2019 03:27:45 +0300 Subject: Fix single quotes parsing (#41) * Fix single quotes parsing Fix e-mails Some small fixes * Mistake in test * More PHP versions --- .travis.yml | 2 + src/NXP/Classes/Calculator.php | 10 +- src/NXP/Classes/Lexer.php | 262 +++++++++++----------- src/NXP/Classes/Token/AbstractContainerToken.php | 2 +- src/NXP/Classes/Token/AbstractOperator.php | 2 +- src/NXP/Classes/Token/InterfaceFunction.php | 2 +- src/NXP/Classes/Token/InterfaceOperator.php | 2 +- src/NXP/Classes/Token/InterfaceToken.php | 2 +- src/NXP/Classes/Token/TokenComma.php | 2 +- src/NXP/Classes/Token/TokenDegree.php | 2 +- src/NXP/Classes/Token/TokenDivision.php | 2 +- src/NXP/Classes/Token/TokenFunction.php | 2 +- src/NXP/Classes/Token/TokenLeftBracket.php | 2 +- src/NXP/Classes/Token/TokenMinus.php | 2 +- src/NXP/Classes/Token/TokenMultiply.php | 2 +- src/NXP/Classes/Token/TokenNumber.php | 2 +- src/NXP/Classes/Token/TokenPlus.php | 2 +- src/NXP/Classes/Token/TokenRightBracket.php | 2 +- src/NXP/Classes/Token/TokenString.php | 25 --- src/NXP/Classes/Token/TokenStringDoubleQuoted.php | 25 +++ src/NXP/Classes/Token/TokenStringSingleQuoted.php | 26 +++ src/NXP/Classes/Token/TokenVariable.php | 2 +- src/NXP/Classes/TokenFactory.php | 26 ++- src/NXP/Exception/IncorrectBracketsException.php | 2 +- src/NXP/Exception/UnknownVariableException.php | 2 +- src/NXP/MathExecutor.php | 27 ++- tests/MathTest.php | 18 +- 27 files changed, 255 insertions(+), 202 deletions(-) delete mode 100644 src/NXP/Classes/Token/TokenString.php create mode 100644 src/NXP/Classes/Token/TokenStringDoubleQuoted.php create mode 100644 src/NXP/Classes/Token/TokenStringSingleQuoted.php diff --git a/.travis.yml b/.travis.yml index 47d1020..551e6ed 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,9 @@ language: php php: - 5.6 + - 7.1 - 7.2 + - 7.3 before_script: - wget http://getcomposer.org/composer.phar diff --git a/src/NXP/Classes/Calculator.php b/src/NXP/Classes/Calculator.php index 253e70c..1ceac84 100644 --- a/src/NXP/Classes/Calculator.php +++ b/src/NXP/Classes/Calculator.php @@ -13,13 +13,14 @@ namespace NXP\Classes; use NXP\Classes\Token\InterfaceOperator; use NXP\Classes\Token\TokenFunction; use NXP\Classes\Token\TokenNumber; -use NXP\Classes\Token\TokenString; +use NXP\Classes\Token\TokenStringSingleQuoted; +use NXP\Classes\Token\TokenStringDoubleQuoted; use NXP\Classes\Token\TokenVariable; use NXP\Exception\IncorrectExpressionException; use NXP\Exception\UnknownVariableException; /** - * @author Alexander Kiryukhin + * @author Alexander Kiryukhin */ class Calculator { @@ -38,7 +39,10 @@ class Calculator if ($token instanceof TokenNumber) { array_push($stack, $token); } - if ($token instanceof TokenString) { + if ($token instanceof TokenStringDoubleQuoted) { + array_push($stack, $token); + } + if ($token instanceof TokenStringSingleQuoted) { array_push($stack, $token); } if ($token instanceof TokenVariable) { diff --git a/src/NXP/Classes/Lexer.php b/src/NXP/Classes/Lexer.php index 36eb43c..a511c9b 100644 --- a/src/NXP/Classes/Lexer.php +++ b/src/NXP/Classes/Lexer.php @@ -1,133 +1,129 @@ - - */ -class Lexer -{ - /** - * @var TokenFactory - */ - private $tokenFactory; - - public function __construct($tokenFactory) - { - $this->tokenFactory = $tokenFactory; - } - - /** - * @param string $input Source string of equation - * @return array Tokens stream - * @throws \NXP\Exception\IncorrectExpressionException - */ - public function stringToTokensStream($input) - { - $matches = []; - preg_match_all($this->tokenFactory->getTokenParserRegex(), $input, $matches); - $tokenFactory = $this->tokenFactory; - $tokensStream = array_map( - function ($token) use ($tokenFactory) { - return $tokenFactory->createToken($token); - }, - $matches[0] - ); - - return $tokensStream; - } - - /** - * @param array $tokensStream Tokens stream - * @return array Array of tokens in revers polish notation - * @throws \NXP\Exception\IncorrectExpressionException - */ - public function buildReversePolishNotation($tokensStream) - { - $output = []; - $stack = []; - - foreach ($tokensStream as $token) { - if ($token instanceof TokenString) { - $output[] = $token; - } - elseif ($token instanceof TokenNumber) { - $output[] = $token; - } - elseif ($token instanceof TokenVariable) { - $output[] = $token; - } - elseif ($token instanceof TokenFunction) { - array_push($stack, $token); - } - elseif ($token instanceof AbstractOperator) { - // While we have something on the stack - while (($count = count($stack)) > 0 - && ( - // If it is a function - ($stack[$count-1] instanceof TokenFunction) - - || - // Or the operator at the top of the operator stack - // has (left associative and equal precedence) - // or has greater precedence - (($stack[$count-1] instanceof InterfaceOperator) && - ( - ($stack[$count-1]->getAssociation() == AbstractOperator::LEFT_ASSOC && - $token->getPriority() == $stack[$count-1]->getPriority()) - || - ($stack[$count-1]->getPriority() > $token->getPriority()) - ) - ) - ) - - // And not a left bracket - && ( ! ($stack[$count-1] instanceof TokenLeftBracket)) ) { - $output[] = array_pop($stack); - } - - array_push($stack, $token); - } - elseif ($token instanceof TokenLeftBracket) { - array_push($stack, $token); - } - elseif ($token instanceof TokenRightBracket) { - while (($current = array_pop($stack)) && ( ! ($current instanceof TokenLeftBracket))) { - $output[] = $current; - } - if (!empty($stack) && ($stack[count($stack)-1] instanceof TokenFunction)) { - $output[] = array_pop($stack); - } - } - } - while (!empty($stack)) { - $token = array_pop($stack); - if ($token instanceof TokenLeftBracket || $token instanceof TokenRightBracket) { - throw new IncorrectBracketsException(); - } - $output[] = $token; - } - - return $output; - } -} + + */ +class Lexer +{ + /** + * @var TokenFactory + */ + private $tokenFactory; + + public function __construct($tokenFactory) + { + $this->tokenFactory = $tokenFactory; + } + + /** + * @param string $input Source string of equation + * @return array Tokens stream + */ + public function stringToTokensStream($input) + { + $matches = []; + preg_match_all($this->tokenFactory->getTokenParserRegex(), $input, $matches); + $tokenFactory = $this->tokenFactory; + $tokensStream = array_map( + function ($token) use ($tokenFactory) { + return $tokenFactory->createToken($token); + }, + $matches[0] + ); + + return $tokensStream; + } + + /** + * @param array $tokensStream Tokens stream + * @return array Array of tokens in revers polish notation + * @throws IncorrectBracketsException + */ + public function buildReversePolishNotation($tokensStream) + { + $output = []; + $stack = []; + + foreach ($tokensStream as $token) { + if ($token instanceof TokenStringDoubleQuoted) { + $output[] = $token; + } elseif ($token instanceof TokenStringSingleQuoted) { + $output[] = $token; + } elseif ($token instanceof TokenNumber) { + $output[] = $token; + } elseif ($token instanceof TokenVariable) { + $output[] = $token; + } elseif ($token instanceof TokenFunction) { + array_push($stack, $token); + } elseif ($token instanceof AbstractOperator) { + // While we have something on the stack + while (($count = count($stack)) > 0 + && ( + // If it is a function + ($stack[$count - 1] instanceof TokenFunction) + + || + // Or the operator at the top of the operator stack + // has (left associative and equal precedence) + // or has greater precedence + (($stack[$count - 1] instanceof InterfaceOperator) && + ( + ($stack[$count - 1]->getAssociation() == AbstractOperator::LEFT_ASSOC && + $token->getPriority() == $stack[$count - 1]->getPriority()) + || + ($stack[$count - 1]->getPriority() > $token->getPriority()) + ) + ) + ) + + // And not a left bracket + && (!($stack[$count - 1] instanceof TokenLeftBracket))) { + $output[] = array_pop($stack); + } + + array_push($stack, $token); + } elseif ($token instanceof TokenLeftBracket) { + array_push($stack, $token); + } elseif ($token instanceof TokenRightBracket) { + while (($current = array_pop($stack)) && (!($current instanceof TokenLeftBracket))) { + $output[] = $current; + } + if (!empty($stack) && ($stack[count($stack) - 1] instanceof TokenFunction)) { + $output[] = array_pop($stack); + } + } + } + while (!empty($stack)) { + $token = array_pop($stack); + if ($token instanceof TokenLeftBracket || $token instanceof TokenRightBracket) { + throw new IncorrectBracketsException(); + } + $output[] = $token; + } + + return $output; + } +} diff --git a/src/NXP/Classes/Token/AbstractContainerToken.php b/src/NXP/Classes/Token/AbstractContainerToken.php index 12d49d2..be2da5f 100644 --- a/src/NXP/Classes/Token/AbstractContainerToken.php +++ b/src/NXP/Classes/Token/AbstractContainerToken.php @@ -11,7 +11,7 @@ namespace NXP\Classes\Token; /** - * @author Alexander Kiryukhin + * @author Alexander Kiryukhin */ abstract class AbstractContainerToken implements InterfaceToken { diff --git a/src/NXP/Classes/Token/AbstractOperator.php b/src/NXP/Classes/Token/AbstractOperator.php index 87634d5..8b23ad8 100644 --- a/src/NXP/Classes/Token/AbstractOperator.php +++ b/src/NXP/Classes/Token/AbstractOperator.php @@ -11,7 +11,7 @@ namespace NXP\Classes\Token; /** - * @author Alexander Kiryukhin + * @author Alexander Kiryukhin */ abstract class AbstractOperator implements InterfaceToken, InterfaceOperator { diff --git a/src/NXP/Classes/Token/InterfaceFunction.php b/src/NXP/Classes/Token/InterfaceFunction.php index be867b0..a457d0e 100644 --- a/src/NXP/Classes/Token/InterfaceFunction.php +++ b/src/NXP/Classes/Token/InterfaceFunction.php @@ -11,7 +11,7 @@ namespace NXP\Classes\Token; /** - * @author Alexander Kiryukhin + * @author Alexander Kiryukhin */ interface InterfaceFunction { diff --git a/src/NXP/Classes/Token/InterfaceOperator.php b/src/NXP/Classes/Token/InterfaceOperator.php index da6cdf0..9e3bae1 100644 --- a/src/NXP/Classes/Token/InterfaceOperator.php +++ b/src/NXP/Classes/Token/InterfaceOperator.php @@ -11,7 +11,7 @@ namespace NXP\Classes\Token; /** - * @author Alexander Kiryukhin + * @author Alexander Kiryukhin */ interface InterfaceOperator { diff --git a/src/NXP/Classes/Token/InterfaceToken.php b/src/NXP/Classes/Token/InterfaceToken.php index 86fec91..db07aeb 100644 --- a/src/NXP/Classes/Token/InterfaceToken.php +++ b/src/NXP/Classes/Token/InterfaceToken.php @@ -11,7 +11,7 @@ namespace NXP\Classes\Token; /** - * @author Alexander Kiryukhin + * @author Alexander Kiryukhin */ interface InterfaceToken { diff --git a/src/NXP/Classes/Token/TokenComma.php b/src/NXP/Classes/Token/TokenComma.php index f590e32..6a45595 100644 --- a/src/NXP/Classes/Token/TokenComma.php +++ b/src/NXP/Classes/Token/TokenComma.php @@ -11,7 +11,7 @@ namespace NXP\Classes\Token; /** - * @author Alexander Kiryukhin + * @author Alexander Kiryukhin */ class TokenComma implements InterfaceToken { diff --git a/src/NXP/Classes/Token/TokenDegree.php b/src/NXP/Classes/Token/TokenDegree.php index 3eec23d..273183a 100644 --- a/src/NXP/Classes/Token/TokenDegree.php +++ b/src/NXP/Classes/Token/TokenDegree.php @@ -13,7 +13,7 @@ namespace NXP\Classes\Token; use NXP\Exception\IncorrectExpressionException; /** -* @author Alexander Kiryukhin +* @author Alexander Kiryukhin */ class TokenDegree extends AbstractOperator { diff --git a/src/NXP/Classes/Token/TokenDivision.php b/src/NXP/Classes/Token/TokenDivision.php index 9166d34..4a8f8ce 100644 --- a/src/NXP/Classes/Token/TokenDivision.php +++ b/src/NXP/Classes/Token/TokenDivision.php @@ -14,7 +14,7 @@ use NXP\Exception\IncorrectExpressionException; use NXP\Exception\DivisionByZeroException; /** -* @author Alexander Kiryukhin +* @author Alexander Kiryukhin */ class TokenDivision extends AbstractOperator { diff --git a/src/NXP/Classes/Token/TokenFunction.php b/src/NXP/Classes/Token/TokenFunction.php index 2ed8ace..b2866c3 100644 --- a/src/NXP/Classes/Token/TokenFunction.php +++ b/src/NXP/Classes/Token/TokenFunction.php @@ -11,7 +11,7 @@ namespace NXP\Classes\Token; /** - * @author Alexander Kiryukhin + * @author Alexander Kiryukhin */ class TokenFunction extends AbstractContainerToken implements InterfaceFunction { diff --git a/src/NXP/Classes/Token/TokenLeftBracket.php b/src/NXP/Classes/Token/TokenLeftBracket.php index 0cfdc1a..08165d8 100644 --- a/src/NXP/Classes/Token/TokenLeftBracket.php +++ b/src/NXP/Classes/Token/TokenLeftBracket.php @@ -11,7 +11,7 @@ namespace NXP\Classes\Token; /** - * @author Alexander Kiryukhin + * @author Alexander Kiryukhin */ class TokenLeftBracket implements InterfaceToken { diff --git a/src/NXP/Classes/Token/TokenMinus.php b/src/NXP/Classes/Token/TokenMinus.php index 566c950..ad0b8e5 100644 --- a/src/NXP/Classes/Token/TokenMinus.php +++ b/src/NXP/Classes/Token/TokenMinus.php @@ -13,7 +13,7 @@ namespace NXP\Classes\Token; use NXP\Exception\IncorrectExpressionException; /** -* @author Alexander Kiryukhin +* @author Alexander Kiryukhin */ class TokenMinus extends AbstractOperator { diff --git a/src/NXP/Classes/Token/TokenMultiply.php b/src/NXP/Classes/Token/TokenMultiply.php index 8b173b9..0b1ecfb 100644 --- a/src/NXP/Classes/Token/TokenMultiply.php +++ b/src/NXP/Classes/Token/TokenMultiply.php @@ -13,7 +13,7 @@ namespace NXP\Classes\Token; use NXP\Exception\IncorrectExpressionException; /** -* @author Alexander Kiryukhin +* @author Alexander Kiryukhin */ class TokenMultiply extends AbstractOperator { diff --git a/src/NXP/Classes/Token/TokenNumber.php b/src/NXP/Classes/Token/TokenNumber.php index a7eac57..982e316 100644 --- a/src/NXP/Classes/Token/TokenNumber.php +++ b/src/NXP/Classes/Token/TokenNumber.php @@ -11,7 +11,7 @@ namespace NXP\Classes\Token; /** - * @author Alexander Kiryukhin + * @author Alexander Kiryukhin */ class TokenNumber extends AbstractContainerToken { diff --git a/src/NXP/Classes/Token/TokenPlus.php b/src/NXP/Classes/Token/TokenPlus.php index fe5a1d6..a6e5036 100644 --- a/src/NXP/Classes/Token/TokenPlus.php +++ b/src/NXP/Classes/Token/TokenPlus.php @@ -13,7 +13,7 @@ namespace NXP\Classes\Token; use NXP\Exception\IncorrectExpressionException; /** -* @author Alexander Kiryukhin +* @author Alexander Kiryukhin */ class TokenPlus extends AbstractOperator { diff --git a/src/NXP/Classes/Token/TokenRightBracket.php b/src/NXP/Classes/Token/TokenRightBracket.php index c68473a..306ae0b 100644 --- a/src/NXP/Classes/Token/TokenRightBracket.php +++ b/src/NXP/Classes/Token/TokenRightBracket.php @@ -11,7 +11,7 @@ namespace NXP\Classes\Token; /** - * @author Alexander Kiryukhin + * @author Alexander Kiryukhin */ class TokenRightBracket implements InterfaceToken { diff --git a/src/NXP/Classes/Token/TokenString.php b/src/NXP/Classes/Token/TokenString.php deleted file mode 100644 index cab0711..0000000 --- a/src/NXP/Classes/Token/TokenString.php +++ /dev/null @@ -1,25 +0,0 @@ - - */ -class TokenString extends AbstractContainerToken -{ - /** - * @return string - */ - public static function getRegex() - { - return '"([^"]|"")*"'; - } -} diff --git a/src/NXP/Classes/Token/TokenStringDoubleQuoted.php b/src/NXP/Classes/Token/TokenStringDoubleQuoted.php new file mode 100644 index 0000000..6cff262 --- /dev/null +++ b/src/NXP/Classes/Token/TokenStringDoubleQuoted.php @@ -0,0 +1,25 @@ + + */ +class TokenStringDoubleQuoted extends AbstractContainerToken +{ + /** + * @return string + */ + public static function getRegex() + { + return '"([^"]|"")*"'; + } +} diff --git a/src/NXP/Classes/Token/TokenStringSingleQuoted.php b/src/NXP/Classes/Token/TokenStringSingleQuoted.php new file mode 100644 index 0000000..7a7ab92 --- /dev/null +++ b/src/NXP/Classes/Token/TokenStringSingleQuoted.php @@ -0,0 +1,26 @@ + + * @author Alexander Kiryukhin + */ +class TokenStringSingleQuoted extends AbstractContainerToken +{ + /** + * @return string + */ + public static function getRegex() + { + return "'([^']|'')*'"; + } +} diff --git a/src/NXP/Classes/Token/TokenVariable.php b/src/NXP/Classes/Token/TokenVariable.php index ccd7c83..a4a820a 100644 --- a/src/NXP/Classes/Token/TokenVariable.php +++ b/src/NXP/Classes/Token/TokenVariable.php @@ -11,7 +11,7 @@ namespace NXP\Classes\Token; /** - * @author Alexander Kiryukhin + * @author Alexander Kiryukhin */ class TokenVariable extends AbstractContainerToken { diff --git a/src/NXP/Classes/TokenFactory.php b/src/NXP/Classes/TokenFactory.php index 778cb59..74b5789 100644 --- a/src/NXP/Classes/TokenFactory.php +++ b/src/NXP/Classes/TokenFactory.php @@ -16,14 +16,15 @@ use NXP\Classes\Token\TokenFunction; use NXP\Classes\Token\TokenLeftBracket; use NXP\Classes\Token\TokenNumber; use NXP\Classes\Token\TokenRightBracket; +use NXP\Classes\Token\TokenStringSingleQuoted; use NXP\Classes\Token\TokenVariable; -use NXP\Classes\Token\TokenString; +use NXP\Classes\Token\TokenStringDoubleQuoted; use NXP\Exception\UnknownFunctionException; use NXP\Exception\UnknownOperatorException; use NXP\Exception\UnknownTokenException; /** - * @author Alexander Kiryukhin + * @author Alexander Kiryukhin */ class TokenFactory { @@ -77,8 +78,9 @@ class TokenFactory /** * Add operator - * @param string $operatorClass - * @throws \NXP\Exception\UnknownOperatorException + * @param string $operatorClass + * @throws UnknownOperatorException + * @throws \ReflectionException */ public function addOperator($operatorClass) { @@ -135,9 +137,10 @@ class TokenFactory } return sprintf( - '/(%s)|(%s)|([%s])|(%s)|(%s)|([%s%s%s])/i', + '/(%s)|(%s)|(%s)|([%s])|(%s)|(%s)|([%s%s%s])/i', TokenNumber::getRegex(), - TokenString::getRegex(), + TokenStringDoubleQuoted::getRegex(), + TokenStringSingleQuoted::getRegex(), $operatorsRegex, TokenFunction::getRegex(), TokenVariable::getRegex(), @@ -148,9 +151,10 @@ class TokenFactory } /** - * @param string $token + * @param string $token * @return InterfaceToken * @throws UnknownTokenException + * @throws UnknownFunctionException */ public function createToken($token) { @@ -167,7 +171,11 @@ class TokenFactory } if ($token[0] == '"') { - return new TokenString(str_replace('"', '', $token)); + return new TokenStringDoubleQuoted(str_replace('"', '', $token)); + } + + if ($token[0] == "'") { + return new TokenStringSingleQuoted(str_replace("'", '', $token)); } if ($token == ',') { @@ -184,7 +192,7 @@ class TokenFactory $regex = sprintf('/%s/i', TokenVariable::getRegex()); if (preg_match($regex, $token)) { - return new TokenVariable(substr($token,1)); + return new TokenVariable(substr($token, 1)); } $regex = sprintf('/%s/i', TokenFunction::getRegex()); diff --git a/src/NXP/Exception/IncorrectBracketsException.php b/src/NXP/Exception/IncorrectBracketsException.php index b3e8315..3b2d2b7 100644 --- a/src/NXP/Exception/IncorrectBracketsException.php +++ b/src/NXP/Exception/IncorrectBracketsException.php @@ -12,7 +12,7 @@ namespace NXP\Exception; /** - * @author Alexander Kiryukhin + * @author Alexander Kiryukhin */ class IncorrectBracketsException extends MathExecutorException { diff --git a/src/NXP/Exception/UnknownVariableException.php b/src/NXP/Exception/UnknownVariableException.php index 8c215db..031a603 100644 --- a/src/NXP/Exception/UnknownVariableException.php +++ b/src/NXP/Exception/UnknownVariableException.php @@ -12,7 +12,7 @@ namespace NXP\Exception; /** - * @author Alexander Kiryukhin + * @author Alexander Kiryukhin */ class UnknownVariableException extends MathExecutorException { diff --git a/src/NXP/MathExecutor.php b/src/NXP/MathExecutor.php index 706f8af..d123c09 100644 --- a/src/NXP/MathExecutor.php +++ b/src/NXP/MathExecutor.php @@ -13,7 +13,6 @@ namespace NXP; use NXP\Classes\Calculator; use NXP\Classes\Lexer; -use NXP\Classes\Token; use NXP\Classes\TokenFactory; use NXP\Exception\UnknownVariableException; @@ -66,13 +65,13 @@ class MathExecutor /** * Get a specific var * - * @param string $variable + * @param string $variable * @return integer|float * @throws UnknownVariableException */ public function getVar($variable) { - if (! isset($this->variables[$variable])) { + if (!isset($this->variables[$variable])) { throw new UnknownVariableException("Variable ({$variable}) not set"); } @@ -82,9 +81,10 @@ class MathExecutor /** * Add variable to executor * - * @param string $variable + * @param string $variable * @param integer|float $value * @return MathExecutor + * @throws \Exception */ public function setVar($variable, $value) { @@ -100,9 +100,10 @@ class MathExecutor /** * Add variables to executor * - * @param array $variables - * @param bool $clear Clear previous variables + * @param array $variables + * @param bool $clear Clear previous variables * @return MathExecutor + * @throws \Exception */ public function setVars(array $variables, $clear = true) { @@ -120,7 +121,7 @@ class MathExecutor /** * Remove variable from executor * - * @param string $variable + * @param string $variable * @return MathExecutor */ public function removeVar($variable) @@ -143,8 +144,9 @@ class MathExecutor /** * Add operator to executor * - * @param string $operatorClass Class of operator token + * @param string $operatorClass Class of operator token * @return MathExecutor + * @throws Exception\UnknownOperatorException */ public function addOperator($operatorClass) { @@ -166,10 +168,11 @@ class MathExecutor /** * Add function to executor * - * @param string $name Name of function - * @param callable $function Function - * @param int $places Count of arguments + * @param string $name Name of function + * @param callable $function Function + * @param int $places Count of arguments * @return MathExecutor + * @throws \ReflectionException */ public function addFunction($name, $function = null, $places = 1) { @@ -300,7 +303,7 @@ class MathExecutor { return [ 'pi' => 3.14159265359, - 'e' => 2.71828182846 + 'e' => 2.71828182846 ]; } } diff --git a/tests/MathTest.php b/tests/MathTest.php index 9acdb63..55e0799 100644 --- a/tests/MathTest.php +++ b/tests/MathTest.php @@ -32,7 +32,7 @@ class MathTest extends \PHPUnit_Framework_TestCase /** @var float $phpResult */ eval('$phpResult = ' . $expression . ';'); - $this->assertEquals($calculator->execute($expression), $phpResult); + $this->assertEquals($calculator->execute($expression), $phpResult, "Expression was: ${expression}"); } /** @@ -138,9 +138,23 @@ class MathTest extends \PHPUnit_Framework_TestCase { $calculator = new MathExecutor(); - $calculator->addFunction('round', function ($arg) { return round($arg); }, 1); + $calculator->addFunction('round', function ($arg) { + return round($arg); + }, 1); /** @var float $phpResult */ eval('$phpResult = round(100/30);'); $this->assertEquals($calculator->execute('round(100/30)'), $phpResult); } + + public function testQuotes() + { + $calculator = new MathExecutor(); + $testString = "some, long. arg; with: different-separators!"; + $calculator->addFunction('test', function ($arg) use ($testString) { + $this->assertEquals($arg, $testString); + return 0; + }, 1); + $calculator->execute('test("' . $testString . '")'); // single quotes + $calculator->execute("test('" . $testString . "')"); // double quotes + } } \ No newline at end of file -- cgit v1.2.3 From 0adcdeeb1bcbed83a7cfc5041177485935e278b3 Mon Sep 17 00:00:00 2001 From: Alexander Kiryukhin Date: Fri, 11 Jan 2019 03:44:46 +0300 Subject: Update README.md Deleted `dev` branch --- README.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/README.md b/README.md index f411aa2..b86f9c6 100644 --- a/README.md +++ b/README.md @@ -14,16 +14,10 @@ A simple math expressions calculator * Easily extendable ## Install via Composer: -Stable branch ``` composer require "nxp/math-executor" ``` -Dev branch (currently unsupported) -``` -composer require "nxp/math-executor" "dev-dev" -``` - ## Sample usage: ```php require "vendor/autoload.php"; -- cgit v1.2.3