ILIAS  eassessment Revision 61809
 All Data Structures Namespaces Files Functions Variables Groups Pages
PHPExcel_Calculation_FormulaParser Class Reference
+ Collaboration diagram for PHPExcel_Calculation_FormulaParser:

Public Member Functions

 __construct ($pFormula= '')
 Create a new PHPExcel_Calculation_FormulaParser.
 getFormula ()
 Get Formula.
 getToken ($pId=0)
 Get Token.
 getTokenCount ()
 Get Token count.
 getTokens ()
 Get Tokens.

Data Fields

const QUOTE_DOUBLE = '"'
const QUOTE_SINGLE = '\''
const BRACKET_CLOSE = ']'
const BRACKET_OPEN = '['
const BRACE_OPEN = '{'
const BRACE_CLOSE = '}'
const PAREN_OPEN = '('
const PAREN_CLOSE = ')'
const SEMICOLON = ';'
const WHITESPACE = ' '
const COMMA = ','
const ERROR_START = '#'
const OPERATORS_SN = "+-"
const OPERATORS_INFIX = "+-*/^&=><"
const OPERATORS_POSTFIX = "%"

Private Member Functions

 _parseToTokens ()
 Parse to tokens.

Private Attributes

 $_formula
 $_tokens = array()

Detailed Description

Definition at line 59 of file FormulaParser.php.

Constructor & Destructor Documentation

PHPExcel_Calculation_FormulaParser::__construct (   $pFormula = '')

Create a new PHPExcel_Calculation_FormulaParser.

Parameters
string$pFormulaFormula to parse
Exceptions
Exception

Definition at line 98 of file FormulaParser.php.

References _parseToTokens().

{
// Check parameters
if (is_null($pFormula)) {
throw new Exception("Invalid parameter passed: formula");
}
// Initialise values
$this->_formula = trim($pFormula);
// Parse!
$this->_parseToTokens();
}

+ Here is the call graph for this function:

Member Function Documentation

PHPExcel_Calculation_FormulaParser::_parseToTokens ( )
private

Parse to tokens.

Definition at line 156 of file FormulaParser.php.

References BRACE_CLOSE, BRACE_OPEN, BRACKET_CLOSE, BRACKET_OPEN, COMMA, ERROR_START, OPERATORS_INFIX, OPERATORS_POSTFIX, OPERATORS_SN, PAREN_CLOSE, PAREN_OPEN, QUOTE_DOUBLE, QUOTE_SINGLE, SEMICOLON, PHPExcel_Calculation_FormulaToken\TOKEN_SUBTYPE_CONCATENATION, PHPExcel_Calculation_FormulaToken\TOKEN_SUBTYPE_ERROR, PHPExcel_Calculation_FormulaToken\TOKEN_SUBTYPE_INTERSECTION, PHPExcel_Calculation_FormulaToken\TOKEN_SUBTYPE_LOGICAL, PHPExcel_Calculation_FormulaToken\TOKEN_SUBTYPE_MATH, PHPExcel_Calculation_FormulaToken\TOKEN_SUBTYPE_NOTHING, PHPExcel_Calculation_FormulaToken\TOKEN_SUBTYPE_NUMBER, PHPExcel_Calculation_FormulaToken\TOKEN_SUBTYPE_RANGE, PHPExcel_Calculation_FormulaToken\TOKEN_SUBTYPE_START, PHPExcel_Calculation_FormulaToken\TOKEN_SUBTYPE_STOP, PHPExcel_Calculation_FormulaToken\TOKEN_SUBTYPE_TEXT, PHPExcel_Calculation_FormulaToken\TOKEN_SUBTYPE_UNION, PHPExcel_Calculation_FormulaToken\TOKEN_TYPE_ARGUMENT, PHPExcel_Calculation_FormulaToken\TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken\TOKEN_TYPE_OPERAND, PHPExcel_Calculation_FormulaToken\TOKEN_TYPE_OPERATORINFIX, PHPExcel_Calculation_FormulaToken\TOKEN_TYPE_OPERATORPOSTFIX, PHPExcel_Calculation_FormulaToken\TOKEN_TYPE_OPERATORPREFIX, PHPExcel_Calculation_FormulaToken\TOKEN_TYPE_SUBEXPRESSION, PHPExcel_Calculation_FormulaToken\TOKEN_TYPE_UNKNOWN, PHPExcel_Calculation_FormulaToken\TOKEN_TYPE_WHITESPACE, and WHITESPACE.

Referenced by __construct().

{
// No attempt is made to verify formulas; assumes formulas are derived from Excel, where
// they can only exist if valid; stack overflows/underflows sunk as nulls without exceptions.
// Check if the formula has a valid starting =
$formulaLength = strlen($this->_formula);
if ($formulaLength < 2 || $this->_formula{0} != '=') return;
// Helper variables
$tokens1 = $tokens2 = $stack = array();
$inString = $inPath = $inRange = $inError = false;
$token = $previousToken = $nextToken = null;
$index = 1;
$value = '';
$ERRORS = array("#NULL!", "#DIV/0!", "#VALUE!", "#REF!", "#NAME?", "#NUM!", "#N/A");
$COMPARATORS_MULTI = array(">=", "<=", "<>");
while ($index < $formulaLength) {
// state-dependent character evaluation (order is important)
// double-quoted strings
// embeds are doubled
// end marks token
if ($inString) {
if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE) {
if ((($index + 2) <= $formulaLength) && ($this->_formula{$index + 1} == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE)) {
++$index;
} else {
$inString = false;
$value = "";
}
} else {
$value .= $this->_formula{$index};
}
++$index;
continue;
}
// single-quoted strings (links)
// embeds are double
// end does not mark a token
if ($inPath) {
if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE) {
if ((($index + 2) <= $formulaLength) && ($this->_formula{$index + 1} == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE)) {
++$index;
} else {
$inPath = false;
}
} else {
$value .= $this->_formula{$index};
}
++$index;
continue;
}
// bracked strings (R1C1 range index or linked workbook name)
// no embeds (changed to "()" by Excel)
// end does not mark a token
if ($inRange) {
if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::BRACKET_CLOSE) {
$inRange = false;
}
$value .= $this->_formula{$index};
++$index;
continue;
}
// error values
// end marks a token, determined from absolute list of values
if ($inError) {
$value .= $this->_formula{$index};
++$index;
if (in_array($value, $ERRORS)) {
$inError = false;
$value = "";
}
continue;
}
// scientific notation check
if (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_SN, $this->_formula{$index}) !== false) {
if (strlen($value) > 1) {
if (preg_match("/^[1-9]{1}(\.[0-9]+)?E{1}$/", $this->_formula{$index}) != 0) {
$value .= $this->_formula{$index};
++$index;
continue;
}
}
}
// independent character evaluation (order not important)
// establish state-dependent character evaluations
if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE) {
if (strlen($value > 0)) { // unexpected
$value = "";
}
$inString = true;
++$index;
continue;
}
if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE) {
if (strlen($value) > 0) { // unexpected
$value = "";
}
$inPath = true;
++$index;
continue;
}
if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::BRACKET_OPEN) {
$inRange = true;
++$index;
continue;
}
if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::ERROR_START) {
if (strlen($value) > 0) { // unexpected
$value = "";
}
$inError = true;
++$index;
continue;
}
// mark start and end of arrays and array rows
if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::BRACE_OPEN) {
if (strlen($value) > 0) { // unexpected
$value = "";
}
$tokens1[] = $tmp;
$stack[] = clone $tmp;
$tokens1[] = $tmp;
$stack[] = clone $tmp;
++$index;
continue;
}
if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::SEMICOLON) {
if (strlen($value) > 0) {
$value = "";
}
$tmp = array_pop($stack);
$tmp->setValue("");
$tokens1[] = $tmp;
$tokens1[] = $tmp;
$tokens1[] = $tmp;
$stack[] = clone $tmp;
++$index;
continue;
}
if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::BRACE_CLOSE) {
if (strlen($value) > 0) {
$value = "";
}
$tmp = array_pop($stack);
$tmp->setValue("");
$tokens1[] = $tmp;
$tmp = array_pop($stack);
$tmp->setValue("");
$tokens1[] = $tmp;
++$index;
continue;
}
// trim white-space
if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::WHITESPACE) {
if (strlen($value) > 0) {
$value = "";
}
++$index;
while (($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::WHITESPACE) && ($index < $formulaLength)) {
++$index;
}
continue;
}
// multi-character comparators
if (($index + 2) <= $formulaLength) {
if (in_array(substr($this->_formula, $index, 2), $COMPARATORS_MULTI)) {
if (strlen($value) > 0) {
$value = "";
}
$index += 2;
continue;
}
}
// standard infix operators
if (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_INFIX, $this->_formula{$index}) !== false) {
if (strlen($value) > 0) {
$value = "";
}
++$index;
continue;
}
// standard postfix operators (only one)
if (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_POSTFIX, $this->_formula{$index}) !== false) {
if (strlen($value) > 0) {
$value = "";
}
++$index;
continue;
}
// start subexpression or function
if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::PAREN_OPEN) {
if (strlen($value) > 0) {
$tokens1[] = $tmp;
$stack[] = clone $tmp;
$value = "";
} else {
$tokens1[] = $tmp;
$stack[] = clone $tmp;
}
++$index;
continue;
}
// function, subexpression, or array parameters, or operand unions
if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::COMMA) {
if (strlen($value) > 0) {
$value = "";
}
$tmp = array_pop($stack);
$tmp->setValue("");
$stack[] = $tmp;
} else {
}
++$index;
continue;
}
// stop subexpression
if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::PAREN_CLOSE) {
if (strlen($value) > 0) {
$value = "";
}
$tmp = array_pop($stack);
$tmp->setValue("");
$tokens1[] = $tmp;
++$index;
continue;
}
// token accumulation
$value .= $this->_formula{$index};
++$index;
}
// dump remaining accumulation
if (strlen($value) > 0) {
}
// move tokenList to new set, excluding unnecessary white-space tokens and converting necessary ones to intersections
$tokenCount = count($tokens1);
for ($i = 0; $i < $tokenCount; ++$i) {
$token = $tokens1[$i];
if (isset($tokens1[$i - 1])) {
$previousToken = $tokens1[$i - 1];
} else {
$previousToken = null;
}
if (isset($tokens1[$i + 1])) {
$nextToken = $tokens1[$i + 1];
} else {
$nextToken = null;
}
if (is_null($token)) {
continue;
}
$tokens2[] = $token;
continue;
}
if (is_null($previousToken)) {
continue;
}
if (! (
(($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) ||
(($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) ||
($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND)
) ) {
continue;
}
if (is_null($nextToken)) {
continue;
}
if (! (
(($nextToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && ($nextToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START)) ||
(($nextToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && ($nextToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START)) ||
) ) {
continue;
}
}
// move tokens to final list, switching infix "-" operators to prefix when appropriate, switching infix "+" operators
// to noop when appropriate, identifying operand and infix-operator subtypes, and pulling "@" from function names
$this->_tokens = array();
$tokenCount = count($tokens2);
for ($i = 0; $i < $tokenCount; ++$i) {
$token = $tokens2[$i];
if (isset($tokens2[$i - 1])) {
$previousToken = $tokens2[$i - 1];
} else {
$previousToken = null;
}
if (isset($tokens2[$i + 1])) {
$nextToken = $tokens2[$i + 1];
} else {
$nextToken = null;
}
if (is_null($token)) {
continue;
}
if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX && $token->getValue() == "-") {
if ($i == 0) {
} else if (
(($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) ||
(($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) ||
($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND)
) {
} else {
}
$this->_tokens[] = $token;
continue;
}
if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX && $token->getValue() == "+") {
if ($i == 0) {
continue;
} else if (
(($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) ||
(($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) ||
($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND)
) {
} else {
continue;
}
$this->_tokens[] = $token;
continue;
}
if (strpos("<>=", substr($token->getValue(), 0, 1)) !== false) {
} else if ($token->getValue() == "&") {
} else {
}
$this->_tokens[] = $token;
continue;
}
if (!is_numeric($token->getValue())) {
if (strtoupper($token->getValue()) == "TRUE" || strtoupper($token->getValue() == "FALSE")) {
} else {
}
} else {
}
$this->_tokens[] = $token;
continue;
}
if (strlen($token->getValue() > 0)) {
if (substr($token->getValue(), 0, 1) == "@") {
$token->setValue(substr($token->getValue(), 1));
}
}
}
$this->_tokens[] = $token;
}
}

+ Here is the caller graph for this function:

PHPExcel_Calculation_FormulaParser::getFormula ( )

Get Formula.

Returns
string

Definition at line 116 of file FormulaParser.php.

References $_formula.

{
}
PHPExcel_Calculation_FormulaParser::getToken (   $pId = 0)

Get Token.

Parameters
int$pIdToken id
Returns
string
Exceptions
Exception

Definition at line 127 of file FormulaParser.php.

{
if (isset($this->_tokens[$pId])) {
return $this->_tokens[$pId];
} else {
throw new Exception("Token with id $pId does not exist.");
}
}
PHPExcel_Calculation_FormulaParser::getTokenCount ( )

Get Token count.

Returns
string

Definition at line 140 of file FormulaParser.php.

{
return count($this->_tokens);
}
PHPExcel_Calculation_FormulaParser::getTokens ( )

Get Tokens.

Returns
PHPExcel_Calculation_FormulaToken[]

Definition at line 149 of file FormulaParser.php.

References $_tokens.

{
}

Field Documentation

PHPExcel_Calculation_FormulaParser::$_formula
private

Definition at line 83 of file FormulaParser.php.

Referenced by getFormula().

PHPExcel_Calculation_FormulaParser::$_tokens = array()
private

Definition at line 90 of file FormulaParser.php.

Referenced by getTokens().

const PHPExcel_Calculation_FormulaParser::BRACE_CLOSE = '}'

Definition at line 66 of file FormulaParser.php.

Referenced by _parseToTokens().

const PHPExcel_Calculation_FormulaParser::BRACE_OPEN = '{'

Definition at line 65 of file FormulaParser.php.

Referenced by _parseToTokens().

const PHPExcel_Calculation_FormulaParser::BRACKET_CLOSE = ']'

Definition at line 63 of file FormulaParser.php.

Referenced by _parseToTokens().

const PHPExcel_Calculation_FormulaParser::BRACKET_OPEN = '['

Definition at line 64 of file FormulaParser.php.

Referenced by _parseToTokens().

const PHPExcel_Calculation_FormulaParser::COMMA = ','

Definition at line 71 of file FormulaParser.php.

Referenced by _parseToTokens().

const PHPExcel_Calculation_FormulaParser::ERROR_START = '#'

Definition at line 72 of file FormulaParser.php.

Referenced by _parseToTokens().

const PHPExcel_Calculation_FormulaParser::OPERATORS_INFIX = "+-*/^&=><"

Definition at line 75 of file FormulaParser.php.

Referenced by _parseToTokens().

const PHPExcel_Calculation_FormulaParser::OPERATORS_POSTFIX = "%"

Definition at line 76 of file FormulaParser.php.

Referenced by _parseToTokens().

const PHPExcel_Calculation_FormulaParser::OPERATORS_SN = "+-"

Definition at line 74 of file FormulaParser.php.

Referenced by _parseToTokens().

const PHPExcel_Calculation_FormulaParser::PAREN_CLOSE = ')'

Definition at line 68 of file FormulaParser.php.

Referenced by _parseToTokens().

const PHPExcel_Calculation_FormulaParser::PAREN_OPEN = '('

Definition at line 67 of file FormulaParser.php.

Referenced by _parseToTokens().

const PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE = '"'

Definition at line 61 of file FormulaParser.php.

Referenced by _parseToTokens().

const PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE = '\''

Definition at line 62 of file FormulaParser.php.

Referenced by _parseToTokens().

const PHPExcel_Calculation_FormulaParser::SEMICOLON = ';'

Definition at line 69 of file FormulaParser.php.

Referenced by _parseToTokens().

const PHPExcel_Calculation_FormulaParser::WHITESPACE = ' '

Definition at line 70 of file FormulaParser.php.

Referenced by _parseToTokens().


The documentation for this class was generated from the following file: