Parses and evaluates a given formula.

@return array Returns an array [0 => v1, 1 => v2], where
v1 is 'done' or 'error', and
v2 is a computed result or error message, respectively.
342088
public function getResult()
    {
        // Check that the formula is not empty
        if (!isset($this->formula[0])) {
            $this->correct = 0;
            $this->error_type = 2;
        }

        // Check set variables
        for ($i=0; $i<=count($this->valid_variables)-1; $i++) { 
            if (strlen($this->valid_variables[$i]) != 1  
            || !preg_match('/^([a-z])$/', $this->valid_variables[$i]) === 1
            || $this->valid_variables[$i] == "e") {
                $this->correct = 0;
                $this->error_type = 4;
            }
        }

        $this->prepare($this->formula);
        $this->group($this->formula);

        $open_parentheses_count = substr_count($this->formula, '(');
        $close_parentheses_count = substr_count($this->formula, ')');

        // Check for an equality of opening and closing parentheses
        if ($open_parentheses_count != $close_parentheses_count) {
            $this->correct = 0;
            $this->error_type = 3;
        }

        // Check the syntax is correct when using parentheses
        if (preg_match('/(\)( )?[^\)\+\-\*\/\^ ])|(\(( )*?\))|([^nstgp\(\+\-\*\/\^ ]( )?\()/',
        $this->formula)) {
            $this->correct = 0;
        }

        $processing_formula = $this->formula;

        // Begin a general parse
        while ((strstr($processing_formula, '(') || strstr($processing_formula, ')'))
        && $this->correct) {
            $start_cursor_pos = 0; $end_cursor_pos = 0;
            $this->group($processing_formula, '');
            $temp = $processing_formula;

            while (strstr($temp, '(')) {
                $strlen_temp = strlen($temp);
                for ($i=0; $i<=$strlen_temp-1; $i++) {
                    if (isset($temp[$i]) && $temp[$i] == '(') {
                        $temp = substr($temp, $i+1);
                        $start_cursor_pos = $start_cursor_pos + $i+1;
                    }
                }
            }

            $strlen_temp = strlen($temp);
            for ($i=0; $i<=$strlen_temp-1; $i++) {
                if (isset($temp[$i]) && $temp[$i] == ')') {
                    $end_cursor_pos = $strlen_temp - $i;
                    $temp = substr($temp, 0, $i);
                    break;
                }
            }

            $length = strlen($processing_formula);

            if (!empty($temp)) {
                $temp = $this->parse($temp);
                $checkExp = $this->checkExp($processing_formula, $length, $end_cursor_pos, $temp);
                if (isset($checkExp->result)) {
                    $temp = $checkExp->result;
                    $end_cursor_pos = $checkExp->cursor;
                }
            }

            $processing_formula = substr($processing_formula, 0, $start_cursor_pos-1)
                    .$temp.substr($processing_formula, $length - $end_cursor_pos+1);
        }

        $this->formula = $processing_formula;

        $result = $this->parse($this->formula);

        if ($this->correct) {
            return ['done', $this->round_($result, $this->precision)];
        } else {
            return ['error', $this->errorMsg()];
        }
    }
1237270
public function parsedVal()
    {
        if (!isset($this->parsedVal[$this->lang()])) {
            $val = $this->propertyVal();

            if ($val === null) {
                return null;
            }
            $val = $this->p()->parseVal($val);

            // Could be Translation instance
            // Could be array
            if (isset($val[$this->lang()])) {
                $val = $val[$this->lang()];
            }

            // Doing this in the parseVal method of abstract property
            // was causing multiple && l10n properties not to save.
            if (!is_array($val) && $this->p()->multiple()) {
                $val = explode($this->p()->multipleSeparator(), $val);
            }

            $this->parsedVal[$this->lang()] = $val;
        }
        return $this->parsedVal[$this->lang()];
    }
450366
public function listFunctions()
    {
        $returnValue = array();

        foreach (self::$PHPExcelFunctions as $functionName => $function) {
            if ($function['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY') {
                $returnValue[$functionName] = new PHPExcel_Calculation_Function(
                    $function['category'],
                    $functionName,
                    $function['functionCall']
                );
            }
        }

        return $returnValue;
    }
1289670
private function parseArgs(): array
    {
        if (null === $this->options && count($this->longopts) === 0 && null === $this->userInput) {
            return $this->fixArgs($_SERVER['argv']);
        }

        if (null !== $this->userInput) {
            $this->collectOptionsFromUserInputClass();
        }

        $parseCommandLineOptions = $this->cliOptionParser;
        $parsedVars = $parseCommandLineOptions($this->options, $this->longopts);
        if (false === $parsedVars) {
            throw new \RuntimeException(
                    'Error parsing "' . join(' ', $_SERVER['argv'])
                    . '" with ' . $this->options
                    . ' and ' . join(' ', $this->longopts)
            );
        }

        return $this->fixArgs($_SERVER['argv'], $parsedVars);
    }
1135250
public function calculateFormula($formula)
    {
        //check whether worksheet name is set or not
        if ($this->worksheetName == '')
            throw new Exception('Worksheet name not specified');
        $strURI = Product::$baseProductUri . '/cells/' . $this->getFileName() .
            '/worksheets/' . $this->worksheetName . '/formulaResult?formula=' . $formula;
        $signedURI = Utils::sign($strURI);
        $responseStream = Utils::processCommand($signedURI, 'GET', '', '');
        $json = json_decode($responseStream);
        return $json->Value->Value;

    }
1182957
public function parse()
    {
        // Note: Order is very important here!
        $operators = [
            Expression::OPERATOR_GTE,
            Expression::OPERATOR_LTE,
            Expression::OPERATOR_NOT,
            Expression::OPERATOR_EQ,
            Expression::OPERATOR_GT,
            Expression::OPERATOR_LT
        ];

        foreach ($operators as $operator) {
            $pos = strpos($this->rawExpression, $operator);

            if ($pos) {

                return new Expression(
                    substr($this->rawExpression, 0, $pos),
                    $operator,
                    substr($this->rawExpression, $pos + strlen($operator))
                );
            }
        }

        // Throw an exception if an operator can't be found
        throw new InvalidExpressionException();
    }
287896
public function ResultVariable()
    {
        $this->match(Lexer::T_IDENTIFIER);

        $resultVariable = $this->lexer->token['value'];

        // Defer ResultVariable validation
        $this->deferredResultVariables[] = [
            'expression'   => $resultVariable,
            'nestingLevel' => $this->nestingLevel,
            'token'        => $this->lexer->token,
        ];

        return $resultVariable;
    }
50109
public function toArray(): array
    {
        if (!empty($this->warnings)) {
            $this->status = 'warning';
        } elseif (!empty($this->errors)) {
            $this->status = 'error';
        }

        return [
            'status' => $this->status,
            'errors' => array_merge(array_map(function($x) {
                return ['severity' => 'error', 'message' => $x];
            }, $this->errors), array_map(function($x) {
                return ['severity' => 'warning', 'message' => $x];
            }, $this->warnings)),
            'info' => $this->info
        ];
    }
1283209
public function evaluate() {
		$value = $this->tsValue('value');
		$isActive = $this->tsValue('isActive');

		$sampleData = $this->tsValue('sampleData');
		if ($isActive) {
			$value = preg_replace_callback(self::PLACEHOLDER_REGEX, function($element) use ($sampleData) {
				return ObjectAccess::getPropertyPath($sampleData, $element[1]);
			}, $value);

			return $value;
		} else {
			return $value;
		}
	}
566320
public function getValidationMessage(): array{
        $fields = [];
        foreach ($this->validations as $validation) {
            /* @var Validation $validation */
            if ($validation->getStatus() == Validation::ERROR) {
                if (!isset($fields[$validation->getField()])) {
                    $fields[$validation->getField()] = [];
                }
                var_dump($validation->getMessage());
                array_push($fields[$validation->getField()], $validation->getMessage());
            }
        }
        return $fields;
    }
836806
public static function VARA()
    {
        $returnValue = PHPExcel_Calculation_Functions::DIV0();

        $summerA = $summerB = 0;

        // Loop through arguments
        $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args());
        $aCount = 0;
        foreach ($aArgs as $k => $arg) {
            if ((is_string($arg)) &&
                (PHPExcel_Calculation_Functions::isValue($k))) {
                return PHPExcel_Calculation_Functions::VALUE();
            } elseif ((is_string($arg)) &&
                (!PHPExcel_Calculation_Functions::isMatrixValue($k))) {
            } else {
                // Is it a numeric value?
                if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) {
                    if (is_bool($arg)) {
                        $arg = (integer) $arg;
                    } elseif (is_string($arg)) {
                        $arg = 0;
                    }
                    $summerA += ($arg * $arg);
                    $summerB += $arg;
                    ++$aCount;
                }
            }
        }

        if ($aCount > 1) {
            $summerA *= $aCount;
            $summerB *= $summerB;
            $returnValue = ($summerA - $summerB) / ($aCount * ($aCount - 1));
        }
        return $returnValue;
    }
163747
public function getAST()
    {
        // Parse & build AST
        $AST = $this->QueryLanguage();

        // Process any deferred validations of some nodes in the AST.
        // This also allows post-processing of the AST for modification purposes.
        $this->processDeferredIdentificationVariables();

        if ($this->deferredPartialObjectExpressions) {
            $this->processDeferredPartialObjectExpressions();
        }

        if ($this->deferredPathExpressions) {
            $this->processDeferredPathExpressions($AST);
        }

        if ($this->deferredResultVariables) {
            $this->processDeferredResultVariables();
        }

        if ($this->deferredNewObjectExpressions) {
            $this->processDeferredNewObjectExpressions($AST);
        }

        $this->processRootEntityAliasSelected();

        // TODO: Is there a way to remove this? It may impact the mixed hydration resultset a lot!
        $this->fixIdentificationVariableOrder($AST);

        return $AST;
    }
1090029
public function process()
    {
        $expr = $this->getExpression();
        $min = $expr->getMin();
        $max = $expr->getMax();

        $state = $this->getState();

        $min = (is_float($min)) ? $min : $state[Utils::sanitizeVariableRef($min)]->getValue();
        $max = (is_float($max)) ? $max : $state[Utils::sanitizeVariableRef($max)]->getValue();

        if (is_float($min) && is_float($max)) {

            if ($min <= $max) {
                return new QtiFloat(($min + lcg_value() * (abs($max - $min))));
            } else {
                $msg = "'min':'${min}' is greater than 'max':'${max}'.";
                throw new ExpressionProcessingException($msg, $this, ExpressionProcessingException::LOGIC_ERROR);
            }
        } else {
            $msg = "At least one of the following values is not a float: 'min', 'max'.";
            throw new ExpressionProcessingException($msg, $this, ExpressionProcessingException::WRONG_VARIABLE_BASETYPE);
        }
    }
247677
protected function _parseArgs()
    {
        $cpt = 0;
        $value = $name = '';
        $args = [];
        $body = '';
        while ($token = $this->_stream->current(true)) {
            $body .= $token[1];
            switch ($token[0]) {
                case '(':
                    if ($cpt) {
                        $value .= $token[1];
                    }
                    $cpt++;
                    break;
                case '=':
                    $name = $value;
                    $value = '';
                    break;
                case ')':
                    $cpt--;
                    if ($cpt) {
                        $value .= $token[1];
                        break;
                    }
                    /* Same behavior as comma */
                case ',':
                    $value = trim($value);
                    if ($value !== '') {
                        $name ? $args[trim($name)] = $value : $args[] = $value;
                    }
                    $name = $value = '';
                    break;
                default:
                    $value .= $token[1];
                    break;
            }
            if ($token[1] === ')' && $cpt === 0) {
                break;
            }
            $this->_stream->next();
        }
        return compact('args', 'body');
    }
813039
public function evaluateResult()
	{
		global $debug_statements;

		if ( $debug_statements )
		{
			\XBRL_Log::getInstance()->info( "Process formula" ) ;
		}

		try
		{
			// Check all variables are not all fallback and that preconditions are met
			if ( parent::evaluateResult() )
			{
				$vars = $this->getBindingsAsVars();
				$covered = array();
				$defined = array();

				foreach ( $this->factVariableBindings as $qname => /** @var VariableBinding $binding */ $binding )
				{
					$covered[ $qname ] = $binding->aspectsCovered;
					$defined[ $qname ] = $binding->aspectsDefined;
				}

				$result = $this->value
					? parent::evaluateXPathExpression( $this, $this->valueXPath2expression, $vars )
					: EmptyIterator::$Shared;

				$lastFactBinding = $this->getLastFactBinding();
				if ( ! $lastFactBinding )
				{
					// If a formula has no variables (like a tuple) then there will be no binding so create a dummy one.
					// This is needed so the aspects defined are propagated
					$lastFactBinding = new FactVariableBinding( $this->xbrlInstance, null );
					$lastFactBinding->facts = EmptyIterator::$Shared;
					$lastFactBinding->aspectsDefined = $this->covers;
					$pos = array_search( ASPECT_DIMENSIONS, $lastFactBinding->aspectsDefined );
					if ( $pos !== false ) unset( $lastFactBinding->aspectsDefined[ $pos ] );
				}

				$evaluationResult = array(
					'result' => $result,
					'vars' => $vars,
					'covered' => $covered,
					'defined' => $defined,
					'lastFactBinding' => $lastFactBinding,
					'variableSet' => $this->label,
					'isTuple' => $this instanceof Tuple,
					'GUID' => \XBRL::GUID(),
				);

				$evaluationResult['uncoveredAspectFacts'] = $evaluationResult['lastFactBinding'] instanceof FactVariableBinding
					? $evaluationResult['lastFactBinding']->uncoveredAspectFacts
					: array();

				if ( $this->tupleLocationRule && isset( $this->scopeDependencies[ $this->tupleLocationRule] ) )
				{
					$scopeArc = $this->scopeDependencies[ $this->tupleLocationRule];
					$sourceFormula = $scopeArc['from'];

					// Look for the ScopeVaribleBinding with the same index as the $scopeArc['name']
					$scopeBindingQName = new QName( $scopeArc['name']['originalPrefix'], $scopeArc['name']['namespace'], $scopeArc['name']['name'] );
					if ( isset( $this->factVariableBindings[ $scopeBindingQName->clarkNotation() ] ) )
					{
						/**
						 * @var ScopeVariableBinding $scopeBinding
						 */
						$scopeBinding = $this->factVariableBindings[ $scopeBindingQName->clarkNotation() ];
						if ( $scopeBinding instanceof ScopeVariableBinding )
						{
							$evaluationResult['parentTupleGUID'] = $scopeBinding->scopeFactGUID;
							$evaluationResult['tuple'] = $sourceFormula;
						}
					}

					// // Look for the first previous evaluation that has a variable set value of $source formula
					// $sourceFormulaResults = array_filter( $this->evaluationResults, function( $evaluationResult ) use( $sourceFormula )
					// {
					// 	return $evaluationResult['variableSet'] == $sourceFormula;
					// } );
                    //
					// if ( count( $sourceFormulaResults ) == 1 )
					// {
					// 	$previousResult = reset( $sourceFormulaResults );
					// 	$evaluationIndex = key( $sourceFormulaResults );
                    //
					// 	$evaluationResult['parentTupleGUID'] = $evaluationIndex; // $previousResult['tupleGUID'];
					// 	$evaluationResult['tuple'] = $previousResult['variableSet'];
					// }
					// else
					// {
					// 	// Look for a previous evaluation result from the source formula that has the same uncovered aspect facts
					// 	foreach ( $sourceFormulaResults as $evaluationIndex => $previousResult )
					// 	{
					// 		$commonAspects = array_intersect( array_keys( $previousResult['uncoveredAspectFacts'] ), array_keys( $evaluationResult['uncoveredAspectFacts'] ) );
					// 		foreach ( $commonAspects as $aspect )
					// 		{
					// 			if ( is_null( $previousResult['uncoveredAspectFacts'][ $aspect ] ) || is_null( $evaluationResult['uncoveredAspectFacts'][ $aspect ] ) ) continue;
					// 			/**
					// 			 * @var DOMXPathNavigator $previousFact
					// 			 */
					// 			$previousFact = $previousResult['uncoveredAspectFacts'][ $aspect ];
					// 			/**
					// 			 * @var DOMXPathNavigator $evaluationFact
					// 			 */
					// 			$evaluationFact = $evaluationResult['uncoveredAspectFacts'][ $aspect ];
                    //
					// 			if ( $previousFact->getUnderlyingObject()->getNodePath() != $evaluationFact->getUnderlyingObject()->getNodePath() ) continue;
                    //
					// 			$evaluationResult['parentTupleGUID'] = $evaluationIndex; // $previousResult['tupleGUID'];
					// 			$evaluationResult['tuple'] = $previousResult['variableSet'];
                    //
					// 			break 2;
					// 		}
					// 	}
					// }
				}

				$this->evaluationResults[ $evaluationResult['GUID'] ] = $evaluationResult;

				return true;
			}
		}
		catch( XPath2Exception $ex )
		{
			throw $ex;
		}
		catch( \Exception $ex )
		{
			// Do nothing
		}

		return false;
	}
392446
protected function parse()
    {
        $sectionName = static::GLOBAL_SECTION;
        $values = [];

        try {
            while ($line = fgets($this->handle)) {
                $this->linenumber++;
                $line = trim($line);
                if (empty($line) || substr($line, 0, 1) === ';') {
                    continue;
                }

                if ($this->isSectionHeader($line)) {
                    if ($sectionName === static::GLOBAL_SECTION) {
                        $this->config = $values;
                    } else {
                        $tokens = explode($this->delimiter, $sectionName);
                        $this->config = array_merge_recursive($this->config,
                                                              $this->subdivide($tokens, $values));

                        unset($tokens);
                    }

                    $sectionName = $this->getSectionHeader($line);
                    $values = [];
                    continue;
                }

                list($key, $value) = array_pad(preg_split(static::SPLIT_PATTERN, trim($line), 2), 2, '');

                if ($this->isArrayKey($key)) {
                    if (is_null($array_key = $this->parseArrayKey($key))) {
                        $key = trim(trim($key), '[]');

                        $values[$key][] = $this->parseValue($value);
                    } else {
                        $key = trim(substr($key, 0, strpos($key, '[')));
                        if (!isset($values[$key])) {
                            $values[$key] = [];
                        }

                        $values[$key][$array_key] = $this->parseValue($value);
                    }
                } else {
                    $values[trim($key)] = $this->parseValue($value);
                }
            }
        } catch (\Exception $ex) {
            throw new \RuntimeException("{$ex->getMessage()} Line: {$this->linenumber}.");
        } finally {
            $this->close();
        }

        if ($sectionName === static::GLOBAL_SECTION) {
            $this->config = $values;
        } else {
            $section = $this->subdivide(explode($this->delimiter, $sectionName), $values);
            $this->config = array_merge($this->config, $section);
        }
    }
422653
public static function convertVoteInput (string $formula) : array
    {
        $ranking = explode('>', $formula);

        foreach ($ranking as &$rank_vote) :
            $rank_vote = explode('=', $rank_vote);

            // Del space at start and end
            foreach ($rank_vote as &$value) :
                $value = trim($value);
            endforeach;
        endforeach;

        return $ranking;
    }