aboutsummaryrefslogtreecommitdiff
path: root/src/NXP/Classes/Lexer.php
diff options
context:
space:
mode:
authorNeonXP <frei@neonxp.info>2013-09-06 05:42:09 +0400
committerNeonXP <frei@neonxp.info>2013-09-06 05:42:09 +0400
commit9cdc34290a84093b1c4640118289a7cf56d55125 (patch)
tree2187fa94cc9f152c9196e7bd4fe23a2c81f60ffd /src/NXP/Classes/Lexer.php
parentf172123a0dccdca7651c7ad552175924a16b9458 (diff)
Mass refactoring
Some changes: + Added support of functions with multiple arguments + Added some default function (min, max, avg). just example of multiple arguments :) - Removed variables support (I think they pointless) ~ All tokens now in individual classes ~ Parsing based on regular expressions ~ Fix negative numbers ~ Fix grouping with brackets
Diffstat (limited to 'src/NXP/Classes/Lexer.php')
-rw-r--r--src/NXP/Classes/Lexer.php121
1 files changed, 121 insertions, 0 deletions
diff --git a/src/NXP/Classes/Lexer.php b/src/NXP/Classes/Lexer.php
new file mode 100644
index 0000000..676962d
--- /dev/null
+++ b/src/NXP/Classes/Lexer.php
@@ -0,0 +1,121 @@
+<?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\AbstractOperator;
+use NXP\Classes\Token\InterfaceOperator;
+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\IncorrectBracketsException;
+use NXP\Exception\IncorrectExpressionException;
+
+/**
+ * @author Alexander Kiryukhin <alexander@symdev.org>
+ */
+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 = array();
+ preg_match_all($this->tokenFactory->getTokenParserRegex(), $input, $matches);
+ $tokensStream = array_map(
+ function ($token) {
+ return $this->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 = array();
+ $stack = array();
+
+ foreach ($tokensStream as $token) {
+ if ($token instanceof TokenNumber) {
+ $output[] = $token;
+ }
+ if ($token instanceof TokenFunction) {
+ array_push($stack, $token);
+ }
+ if ($token instanceof TokenLeftBracket) {
+ array_push($stack, $token);
+ }
+ if ($token instanceof TokenComma) {
+ while (($current = array_pop($stack)) && (!$current instanceof TokenLeftBracket)) {
+ $output[] = $current;
+ if (empty($stack)) {
+ throw new IncorrectExpressionException();
+ }
+ }
+ }
+ if ($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);
+ }
+ }
+
+ if ($token instanceof AbstractOperator) {
+ while (
+ count($stack) > 0 &&
+ ($stack[count($stack)-1] instanceof InterfaceOperator) &&
+ (
+ $token->getAssociation() == AbstractOperator::LEFT_ASSOC &&
+ $token->getPriority() <= $stack[count($stack)-1]->getPriority()
+ ) || (
+ $token->getAssociation() == AbstractOperator::RIGHT_ASSOC &&
+ $token->getPriority() < $stack[count($stack)-1]->getPriority()
+ )
+ ) {
+ $output[] = array_pop($stack);
+ }
+
+ array_push($stack, $token);
+ }
+ }
+ while (!empty($stack)) {
+ $token = array_pop($stack);
+ if ($token instanceof TokenLeftBracket || $token instanceof TokenRightBracket) {
+ throw new IncorrectBracketsException();
+ }
+ $output[] = $token;
+ }
+
+ return $output;
+ }
+}