aboutsummaryrefslogtreecommitdiff
path: root/src/NXP/Classes/TokenFactory.php
diff options
context:
space:
mode:
Diffstat (limited to 'src/NXP/Classes/TokenFactory.php')
-rw-r--r--src/NXP/Classes/TokenFactory.php125
1 files changed, 125 insertions, 0 deletions
diff --git a/src/NXP/Classes/TokenFactory.php b/src/NXP/Classes/TokenFactory.php
new file mode 100644
index 0000000..924203d
--- /dev/null
+++ b/src/NXP/Classes/TokenFactory.php
@@ -0,0 +1,125 @@
+<?php
+/**
+ * This file is part of the MathExecutor package
+ *
+ * (c) Alexander Kiryukhin
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code
+ */
+
+namespace NXP\Classes;
+
+use NXP\Classes\Token\InterfaceToken;
+use NXP\Classes\Token\TokenComma;
+use NXP\Classes\Token\TokenFunction;
+use NXP\Classes\Token\TokenLeftBracket;
+use NXP\Classes\Token\TokenNumber;
+use NXP\Classes\Token\TokenRightBracket;
+use NXP\Exception\UnknownFunctionException;
+use NXP\Exception\UnknownOperatorException;
+use NXP\Exception\UnknownTokenException;
+
+/**
+ * @author Alexander Kiryukhin <alexander@symdev.org>
+ */
+class TokenFactory
+{
+ /**
+ * Available operators
+ *
+ * @var array
+ */
+ protected $operators = array();
+
+ /**
+ * Available functions
+ *
+ * @var array
+ */
+ protected $functions = array();
+
+ /**
+ * @param $name
+ * @param $function
+ * @param $places
+ */
+ public function addFunction($name, $function, $places = 1)
+ {
+ $this->functions[$name] = array($places, $function);
+ }
+
+ public function addOperator($operatorClass)
+ {
+ $class = new \ReflectionClass($operatorClass);
+
+ if (!in_array('NXP\Classes\Token\InterfaceToken', $class->getInterfaceNames())) {
+ throw new UnknownOperatorException;
+ }
+
+ $this->operators[] = $operatorClass;
+ $this->operators = array_unique($this->operators);
+ }
+
+ /**
+ * @return string
+ */
+ public function getTokenParserRegex()
+ {
+ $operatorsRegex = '';
+ foreach ($this->operators as $operator) {
+ $operatorsRegex .= $operator::getRegex();
+ }
+
+ return sprintf(
+ '/(%s)|([%s])|(%s)|([%s%s%s])/i',
+ TokenNumber::getRegex(),
+ $operatorsRegex,
+ TokenFunction::getRegex(),
+ TokenLeftBracket::getRegex(),
+ TokenRightBracket::getRegex(),
+ TokenComma::getRegex()
+ );
+ }
+
+ /**
+ * @param string $token
+ * @return InterfaceToken
+ * @throws UnknownTokenException
+ */
+ public function createToken($token)
+ {
+ if (is_numeric($token)) {
+ return new TokenNumber($token);
+ }
+
+ if ($token == '(') {
+ return new TokenLeftBracket();
+ }
+
+ if ($token == ')') {
+ return new TokenRightBracket();
+ }
+
+ if ($token == ',') {
+ return new TokenComma();
+ }
+
+ foreach ($this->operators as $operator) {
+ $regex = sprintf('/%s/i', $operator::getRegex());
+ if (preg_match($regex, $token)) {
+ return new $operator;
+ }
+ }
+
+ $regex = sprintf('/%s/i', TokenFunction::getRegex());
+ if (preg_match($regex, $token)) {
+ if (isset($this->functions[$token])) {
+ return new TokenFunction($this->functions[$token]);
+ } else {
+ throw new UnknownFunctionException();
+ }
+ }
+ throw new UnknownTokenException();
+ }
+}