aboutsummaryrefslogtreecommitdiff
path: root/src/NXP/Classes
diff options
context:
space:
mode:
authorAlexander Kiryukhin <frei@neonxp.info>2013-08-03 15:15:02 +0400
committerAlexander Kiryukhin <frei@neonxp.info>2013-08-03 15:15:02 +0400
commitf172123a0dccdca7651c7ad552175924a16b9458 (patch)
treee093d7928420255e986acb44d4ab34634f601c52 /src/NXP/Classes
parent253fb694a3fcafa3f9ea6da6681f0b176cdec1f4 (diff)
parenteb9c3651614dd5e5aef067880092e9f622c264df (diff)
Merge pull request #3 from ZhukV/master
Fix to PSR standart, fix tokenizer, fix function executor.
Diffstat (limited to 'src/NXP/Classes')
-rw-r--r--src/NXP/Classes/Func.php45
-rw-r--r--src/NXP/Classes/Operand.php89
-rw-r--r--src/NXP/Classes/Token.php56
-rw-r--r--src/NXP/Classes/TokenParser.php165
4 files changed, 355 insertions, 0 deletions
diff --git a/src/NXP/Classes/Func.php b/src/NXP/Classes/Func.php
new file mode 100644
index 0000000..e8c0fa2
--- /dev/null
+++ b/src/NXP/Classes/Func.php
@@ -0,0 +1,45 @@
+<?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;
+
+class Func
+{
+ /**
+ * @var string
+ */
+ private $name;
+
+ /**
+ * @var callable
+ */
+ private $callback;
+
+ /**
+ * @param $name
+ * @param $callback
+ */
+ public function __construct($name, $callback)
+ {
+ $this->name = $name;
+ $this->callback = $callback;
+ }
+
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ public function getCallback()
+ {
+ return $this->callback;
+ }
+}
diff --git a/src/NXP/Classes/Operand.php b/src/NXP/Classes/Operand.php
new file mode 100644
index 0000000..fae0c69
--- /dev/null
+++ b/src/NXP/Classes/Operand.php
@@ -0,0 +1,89 @@
+<?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;
+
+class Operand
+{
+ const LEFT_ASSOCIATED = 'LEFT_ASSOCIATED';
+ const RIGHT_ASSOCIATED = 'RIGHT_ASSOCIATED';
+ const ASSOCIATED = 'ASSOCIATED';
+
+ const UNARY = 'UNARY';
+ const BINARY = 'BINARY';
+
+ /**
+ * @var string
+ */
+ private $symbol;
+
+ /**
+ * @var int
+ */
+ private $priority;
+
+ /**
+ * @var string
+ */
+ private $association;
+
+ /**
+ * @var string
+ */
+ private $type;
+
+ /**
+ * @var callable
+ */
+ private $callback;
+
+ /**
+ * @param $symbol
+ * @param $priority
+ * @param $association
+ * @param $type
+ * @param $callback
+ */
+ public function __construct($symbol, $priority, $association, $type, $callback)
+ {
+ $this->association = $association;
+ $this->symbol = $symbol;
+ $this->type = $type;
+ $this->priority = $priority;
+ $this->callback = $callback;
+ }
+
+ public function getAssociation()
+ {
+ return $this->association;
+ }
+
+ public function getSymbol()
+ {
+ return $this->symbol;
+ }
+
+ public function getType()
+ {
+ return $this->type;
+ }
+
+ public function getCallback()
+ {
+ return $this->callback;
+ }
+
+ public function getPriority()
+ {
+ return $this->priority;
+ }
+
+}
diff --git a/src/NXP/Classes/Token.php b/src/NXP/Classes/Token.php
new file mode 100644
index 0000000..bbcd5bc
--- /dev/null
+++ b/src/NXP/Classes/Token.php
@@ -0,0 +1,56 @@
+<?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;
+
+class Token
+{
+ const NOTHING = 'NOTHING';
+ const STRING = 'STRING';
+ const NUMBER = 'NUMBER';
+ const OPERATOR = 'OPERATOR';
+ const LEFT_BRACKET = 'LEFT_BRACKET';
+ const RIGHT_BRACKET = 'RIGHT_BRACKET';
+ const FUNC = 'FUNC';
+
+ /**
+ * @var string
+ */
+ protected $value;
+
+ /**
+ * @var string
+ */
+ protected $type;
+
+ public function __construct($type, $value)
+ {
+ $this->type = $type;
+ $this->value = $value;
+ }
+
+ /**
+ * @return string
+ */
+ public function getType()
+ {
+ return $this->type;
+ }
+
+ /**
+ * @return string
+ */
+ public function getValue()
+ {
+ return $this->value;
+ }
+
+}
diff --git a/src/NXP/Classes/TokenParser.php b/src/NXP/Classes/TokenParser.php
new file mode 100644
index 0000000..f498184
--- /dev/null
+++ b/src/NXP/Classes/TokenParser.php
@@ -0,0 +1,165 @@
+<?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;
+
+class TokenParser
+{
+ const DIGIT = 'DIGIT';
+ const CHAR = 'CHAR';
+ const SPECIAL_CHAR = 'SPECIAL_CHAR';
+ const LEFT_BRACKET = 'LEFT_BRACKET';
+ const RIGHT_BRACKET = 'RIGHT_BRACKET';
+ const SPACE = 'SPACE';
+
+ private $terms = array(
+ self::DIGIT => '[0-9\.]',
+ self::CHAR => '[a-z_]',
+ self::SPECIAL_CHAR => '[\!\@\#\$\%\^\&\*\/\|\-\+\=\~]',
+ self::LEFT_BRACKET => '\(',
+ self::RIGHT_BRACKET => '\)',
+ self::SPACE => '\s'
+ );
+
+ const ERROR_STATE = 'ERROR_STATE';
+
+ private $transitions = array(
+ Token::NOTHING => array(
+ self::DIGIT => Token::NUMBER,
+ self::CHAR => Token::STRING,
+ self::SPECIAL_CHAR => Token::OPERATOR,
+ self::LEFT_BRACKET => Token::LEFT_BRACKET,
+ self::RIGHT_BRACKET => Token::RIGHT_BRACKET,
+ self::SPACE => Token::NOTHING
+ ),
+ Token::STRING => array(
+ self::DIGIT => Token::STRING,
+ self::CHAR => Token::STRING,
+ self::SPECIAL_CHAR => Token::OPERATOR,
+ self::LEFT_BRACKET => Token::LEFT_BRACKET,
+ self::RIGHT_BRACKET => Token::RIGHT_BRACKET,
+ self::SPACE => Token::NOTHING
+ ),
+ Token::NUMBER => array(
+ self::DIGIT => Token::NUMBER,
+ self::CHAR => self::ERROR_STATE,
+ self::SPECIAL_CHAR => Token::OPERATOR,
+ self::LEFT_BRACKET => Token::LEFT_BRACKET,
+ self::RIGHT_BRACKET => Token::RIGHT_BRACKET,
+ self::SPACE => Token::NOTHING
+ ),
+ Token::OPERATOR => array(
+ self::DIGIT => Token::NUMBER,
+ self::CHAR => Token::STRING,
+ self::SPECIAL_CHAR => Token::OPERATOR,
+ self::LEFT_BRACKET => Token::LEFT_BRACKET,
+ self::RIGHT_BRACKET => Token::RIGHT_BRACKET,
+ self::SPACE => Token::NOTHING
+ ),
+ self::ERROR_STATE => array(
+ self::DIGIT => self::ERROR_STATE,
+ self::CHAR => self::ERROR_STATE,
+ self::SPECIAL_CHAR => self::ERROR_STATE,
+ self::LEFT_BRACKET => self::ERROR_STATE,
+ self::RIGHT_BRACKET => self::ERROR_STATE,
+ self::SPACE => self::ERROR_STATE
+ ),
+ Token::LEFT_BRACKET => array(
+ self::DIGIT => Token::NUMBER,
+ self::CHAR => Token::STRING,
+ self::SPECIAL_CHAR => Token::OPERATOR,
+ self::LEFT_BRACKET => Token::LEFT_BRACKET,
+ self::RIGHT_BRACKET => Token::RIGHT_BRACKET,
+ self::SPACE => Token::NOTHING
+ ),
+ Token::RIGHT_BRACKET => array(
+ self::DIGIT => Token::NUMBER,
+ self::CHAR => Token::STRING,
+ self::SPECIAL_CHAR => Token::OPERATOR,
+ self::LEFT_BRACKET => Token::LEFT_BRACKET,
+ self::RIGHT_BRACKET => Token::RIGHT_BRACKET,
+ self::SPACE => Token::NOTHING
+ ),
+ );
+
+ private $accumulator = '';
+
+ private $state = Token::NOTHING;
+
+ private $queue = null;
+
+ public function __construct()
+ {
+ $this->queue = new \SplQueue();
+ }
+
+ /**
+ * Tokenize math expression
+ * @param $expression
+ * @return \SplQueue
+ * @throws \Exception
+ */
+ public function tokenize($expression)
+ {
+ $oldState = null;
+ for ($i=0; $i<strlen($expression); $i++) {
+ $char = substr($expression, $i, 1);
+ $class = $this->getSymbolType($char);
+ $oldState = $this->state;
+ $this->state = $this->transitions[$this->state][$class];
+ if ($this->state == self::ERROR_STATE) {
+ throw new \Exception("Parse expression error at $i column (symbol '$char')");
+ }
+ $this->addToQueue($oldState);
+ $this->accumulator .= $char;
+ }
+ if (!empty($this->accumulator)) {
+ $token = new Token($this->state, $this->accumulator);
+ $this->queue->push($token);
+ }
+
+ return $this->queue;
+ }
+
+ /**
+ * @param $symbol
+ * @return string
+ * @throws \Exception
+ */
+ private function getSymbolType($symbol)
+ {
+ foreach ($this->terms as $class => $regex) {
+ if (preg_match("/$regex/i", $symbol)) {
+ return $class;
+ }
+ }
+
+ throw new \Exception("Unknown char '$symbol'");
+ }
+
+ /**
+ * @param $oldState
+ */
+ private function addToQueue($oldState)
+ {
+ if ($oldState == Token::NOTHING) {
+ $this->accumulator = '';
+
+ return;
+ }
+
+ if (($this->state != $oldState) || ($oldState == Token::LEFT_BRACKET) || ($oldState == Token::RIGHT_BRACKET)) {
+ $token = new Token($oldState, $this->accumulator);
+ $this->queue->push($token);
+ $this->accumulator = '';
+ }
+ }
+}