• Модуль: bizproc
  • Путь к файлу: ~/bitrix/modules/bizproc/classes/general/calc.php
  • Класс: CBPCalc
  • Вызов: CBPCalc::getPolishNotation
private function getPolishNotation($text)
{
	$text = trim($text);
	if (mb_substr($text, 0, 1) === '=')
		$text = mb_substr($text, 1);
	if (mb_strpos($text, '{{=') === 0 && mb_substr($text, -2) == '}}')
	{
		$text = mb_substr($text, 3);
		$text = mb_substr($text, 0, -2);
	}

	if ($text == '')
	{
		$this->SetError(1);
		return false;
	}

	$arPolishNotation = $arStack = [];
	$prev = '';
	$preg = '/
		s*(s*                          |
		s*)s*                          |
		s*,s*                           | # Combine ranges of variables
		s*;s*                           | # Combine ranges of variables
		s*=s*                           |
		s*<=s*                          |
		s*>=s*                          |
		s*<>s*                          |
		s*s*                           |
		s*&s*                           | # String concatenation
		s*+s*                          | # Addition or unary plus
		s*-s*                           |
		s**s*                          |
		s*/s*                          |
		s*^s*                          | # Exponentiation
		s*%s*                           | # Percent
		s*[d.]+s*                     | # Numbers
		s*'[^']*'s*                  | # String constants in apostrophes
		s*"[^"]*"s*                     | # String constants in quotes
		(s*w+s*(s*)                  | # Function names
		s*'.CBPActivity::ValueInternalPattern.'s*  | # Variables
		(?.+)                                # Any erroneous substring
		/xi';
	while (preg_match($preg, $text, $match))
	{
		if (isset($match['error']))
		{
			$this->SetError(2, $match['error']);
			return false;
		}

		$str = trim($match[0]);
		if ($str === ",")
			$str = ";";

		if (isset($match[1]) && $match[1])
		{
			$str = mb_strtolower($str);
			list($name, $left) = explode('(', $str);
			$name = trim($name);
			if (isset($this->arAvailableFunctions[$name]))
			{
				if (!$arStack)
				{
					array_unshift($arStack, [$name, $this->arPriority['f']]);
				}
				else
				{
					while ($this->arPriority['f'] <= $arStack[0][1])
					{
						$op = array_shift($arStack);
						$arPolishNotation[] = [$op[0], self::Operation];
						if (!$arStack)
							break;
					}
					array_unshift($arStack, [$name, $this->arPriority['f']]);
				}
			}
			else
			{
				$this->SetError(3, $name);
				return false;
			}
			$str = '(';
		}

		if ($str == '-' || $str == '+')
		{
			if ($prev == '' || in_array($prev, ['(', ';', '=', '<=', '>=', '<>', '<', '>', '&', '+', '-', '*', '/', '^']))
				$str .= 'm';
		}
		$prev = $str;

		switch ($str)
		{
			case '(':
				array_unshift($arStack, ['(', $this->arPriority['(']]);
				break;
			case ')':
				while ($op = array_shift($arStack))
				{
					if ($op[0] == '(')
						break;
					$arPolishNotation[] = [$op[0], self::Operation];
				}
				if ($op == null)
				{
					$this->SetError(4);
					return false;
				}
				break;
			case ';' :      case '=' :      case '<=':      case '>=':
			case '<>':      case '<' :      case '>' :      case '&' :
			case '+' :      case '-' :      case '+m':      case '-m':
			case '*' :      case '/' :      case '^' :      case '%' :
				if (!$arStack)
				{
					array_unshift($arStack, [$str, $this->arPriority[$str]]);
					break;
				}
				while ($this->arPriority[$str] <= $arStack[0][1])
				{
					$op = array_shift($arStack);
					$arPolishNotation[] = [$op[0], self::Operation];
					if (!$arStack)
						break;
				}
				array_unshift($arStack, [$str, $this->arPriority[$str]]);
				break;
			default:
				if (mb_substr($str, 0, 1) == '0' || (int) $str)
				{
					$arPolishNotation[] = [(float)$str, self::Constant];
					break;
				}
				if (mb_substr($str, 0, 1) == '"' || mb_substr($str, 0, 1) == "'")
				{
					$arPolishNotation[] = [mb_substr($str, 1, -1), self::Constant];
					break;
				}
				$arPolishNotation[] = [$str, self::Variable];
		}
		$text = mb_substr($text, mb_strlen($match[0]));
	}
	while ($op = array_shift($arStack))
	{
		if ($op[0] == '(')
		{
			$this->SetError(5);
			return false;
		}
		$arPolishNotation[] = [$op[0], self::Operation];
	}
	return $arPolishNotation;
}