ILIAS  Release_5_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
ilDclExpressionParser Class Reference

Class ilDclExpressionParser. More...

+ Collaboration diagram for ilDclExpressionParser:

Public Member Functions

 __construct ($expression, ilDataCollectionRecord $record, ilDataCollectionField $field)
 parse ()
 Parse expression and return result.

Static Public Member Functions

static getOperators ()
static getFunctions ()

Data Fields

const N_DECIMALS = 1
const SCIENTIFIC_NOTATION_UPPER = 1000000000000
const SCIENTIFIC_NOTATION_LOWER = 0.000000001

Protected Member Functions

 formatScientific ($value)
 isMathToken ($token)
 Check if a given token is a math expression.
 calculateFunctions ($token)
 Execute any math functions inside a token.
 getFunctionArgs ($index, array $data)
 Helper method to return the function and its arguments from a preg_replace_all $result array.
 substituteFieldValues (array $tokens)
 Given an array of tokens, replace each token that is a placeholder (e.g.
 parseMath (array $tokens)
 Parse a math expression.
 calculateFunction ($function, array $args=array())
 Calculate a function with its arguments.
 calculate ($operator, $left, $right)

Protected Attributes

 $record
 $field
 $expression

Static Protected Attributes

static $operators
static $cache_tokens = array()
static $cache_fields = array()
static $cache_math_tokens = array()
static $cache_math_function_tokens = array()
static $functions

Detailed Description

Constructor & Destructor Documentation

ilDclExpressionParser::__construct (   $expression,
ilDataCollectionRecord  $record,
ilDataCollectionField  $field 
)
Parameters
string$expression
ilDataCollectionRecord$record
ilDataCollectionField$field

Definition at line 68 of file class.ilDclExpressionParser.php.

References $expression, $field, and $record.

{
$this->expression = $expression;
$this->record = $record;
$this->field = $field;
}

Member Function Documentation

ilDclExpressionParser::calculate (   $operator,
  $left,
  $right 
)
protected
Parameters
string$operator
float$left
float$right
Returns
float|number
Exceptions
ilException

Definition at line 416 of file class.ilDclExpressionParser.php.

References $result.

Referenced by parseMath().

{
switch ($operator) {
case '+':
$result = $left + $right;
break;
case '-':
$result = $left - $right;
break;
case '*':
$result = $left * $right;
break;
case '/':
$result = ($right == 0) ? 0 : $left / $right;
break;
case '^':
$result = pow($left, $right);
break;
default:
throw new ilException("Unrecognized operator '$operator'");
}
return $result;
}

+ Here is the caller graph for this function:

ilDclExpressionParser::calculateFunction (   $function,
array  $args = array() 
)
protected

Calculate a function with its arguments.

Parameters
$functionFunction name to calculate
array$argsArguments of function
Returns
float|int|number
Exceptions
ilException

Definition at line 390 of file class.ilDclExpressionParser.php.

Referenced by calculateFunctions().

{
switch ($function) {
case 'AVERAGE':
$count = count($args);
return ($count) ? array_sum($args) / $count : 0;
case 'SUM':
return array_sum($args);
case 'MIN':
return min($args);
case 'MAX':
return max($args);
default:
throw new ilException("Unrecognized function '$function'");
}
}

+ Here is the caller graph for this function:

ilDclExpressionParser::calculateFunctions (   $token)
protected

Execute any math functions inside a token.

Parameters
string$token
Returns
string

Definition at line 187 of file class.ilDclExpressionParser.php.

References $result, calculateFunction(), getFunctionArgs(), and substituteFieldValues().

Referenced by parse().

{
if (isset(self::$cache_math_function_tokens[$this->field->getId()][$token])) {
$result = self::$cache_math_function_tokens[$this->field->getId()][$token];
if ($result === false) {
return $token;
}
} else {
$pattern = '#';
foreach (self::getFunctions() as $function) {
$pattern .= "($function)\\(([^)]*)\\)|";
}
if (!preg_match_all(rtrim($pattern, '|') . '#', $token, $result)) {
// No functions found inside token, just return token again
self::$cache_math_function_tokens[$this->field->getId()][$token] = false;
return $token;
}
}
// Function found inside token, calculate!
foreach ($result[0] as $k => $to_replace) {
$function_args = $this->getFunctionArgs($k, $result);
$function = $function_args['function'];
$args = $this->substituteFieldValues($function_args['args']);
$token = str_replace($to_replace, $this->calculateFunction($function, $args), $token);
}
return $token;
}

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

ilDclExpressionParser::formatScientific (   $value)
protected
Parameters
$value
Returns
string

Definition at line 125 of file class.ilDclExpressionParser.php.

Referenced by parse().

{
if ($value >= self::SCIENTIFIC_NOTATION_UPPER) {
return sprintf("%e", $value);
}
if ($value <= self::SCIENTIFIC_NOTATION_LOWER) {
return sprintf("%e", $value);
}
if (is_float($value)) {
return $value;
}
return $value;
}

+ Here is the caller graph for this function:

ilDclExpressionParser::getFunctionArgs (   $index,
array  $data 
)
protected

Helper method to return the function and its arguments from a preg_replace_all $result array.

Parameters
$index
array$data
Returns
array

Definition at line 225 of file class.ilDclExpressionParser.php.

Referenced by calculateFunctions().

{
$return = array(
'function' => '',
'args' => array(),
);
for ($i = 1; $i < count($data); $i ++) {
$_data = $data[$i];
if ($_data[$index]) {
$function = $_data[$index];
$args = explode(';', $data[$i + 1][$index]);
$return['function'] = $function;
$return['args'] = $args;
break;
}
}
return $return;
}

+ Here is the caller graph for this function:

static ilDclExpressionParser::getFunctions ( )
static
Returns
array

Definition at line 151 of file class.ilDclExpressionParser.php.

References $functions.

Referenced by ilDataCollectionFieldEditGUI\initForm(), and isMathToken().

{
}

+ Here is the caller graph for this function:

static ilDclExpressionParser::getOperators ( )
static
Returns
array

Definition at line 143 of file class.ilDclExpressionParser.php.

References $operators.

Referenced by ilDclTokenizer\getMathTokens(), and ilDataCollectionFieldEditGUI\initForm().

{
}

+ Here is the caller graph for this function:

ilDclExpressionParser::isMathToken (   $token)
protected

Check if a given token is a math expression.

Parameters
string$token
Returns
bool

Definition at line 163 of file class.ilDclExpressionParser.php.

References $functions, $operators, $result, and getFunctions().

Referenced by parse().

{
if (isset(self::$cache_math_tokens[$this->field->getId()][$token])) {
return self::$cache_math_tokens[$this->field->getId()][$token];
} else {
if (strpos($token, '"') === 0) {
return false;
}
$operators = array_keys(self::getOperators());
$result = (bool)preg_match('#(\\' . implode("|\\", $operators) . '|' . implode('|', $functions) . ')#', $token);
self::$cache_math_tokens[$this->field->getId()][$token] = $result;
return $result;
}
}

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

ilDclExpressionParser::parse ( )

Parse expression and return result.

This method loops the tokens and checks if Token is of type string or math. Concatenates results to produce resulting string of parsed expression.

Exceptions
ilException
Returns
string

Definition at line 83 of file class.ilDclExpressionParser.php.

References calculateFunctions(), formatScientific(), ilDclTokenizer\getMathTokens(), ilDclTokenizer\getTokens(), isMathToken(), parseMath(), and substituteFieldValues().

{
if (isset(self::$cache_tokens[$this->field->getId()])) {
$tokens = self::$cache_tokens[$this->field->getId()];
} else {
$tokens = ilDclTokenizer::getTokens($this->expression);
self::$cache_tokens[$this->field->getId()] = $tokens;
}
// ilUtil::sendInfo( "<pre>" . print_r($tokens, 1) . "</pre>");
$parsed = '';
foreach ($tokens as $token) {
if (empty($token)) {
continue;
}
if ($this->isMathToken($token)) {
$token = $this->calculateFunctions($token);
$math_tokens = ilDclTokenizer::getMathTokens($token);
$value = $this->parseMath($this->substituteFieldValues($math_tokens));
$value = $this->formatScientific($value);
$parsed .= $value;
} else {
// Token is a string, either a field placeholder [[Field name]] or a string starting with "
if (strpos($token, '"') === 0) {
$parsed .= strip_tags(trim($token, '"'));
} elseif (strpos($token, '[[') === 0) {
$parsed .= trim(strip_tags($this->substituteFieldValue($token)));
} else {
throw new ilException("Unrecognized string token: '$token'");
}
}
}
return $parsed;
}

+ Here is the call graph for this function:

ilDclExpressionParser::parseMath ( array  $tokens)
protected

Parse a math expression.

Parameters
array$tokens
Returns
null
Exceptions
Exception

Definition at line 309 of file class.ilDclExpressionParser.php.

References $operators, $result, and calculate().

Referenced by parse().

{
$precedence = 0;
$stack = new ilDclStack();
$precedences = new ilDclStack();
$in_bracket = false;
foreach ($tokens as $token) {
if (empty($token) OR is_null($token)) {
$token = 0;
}
if (is_numeric($token) OR $token === '(') {
$stack->push($token);
if ($token === '(') {
$in_bracket = true;
}
} elseif (in_array($token, array_keys($operators))) {
$new_precedence = $operators[$token]['precedence'];
if ($new_precedence > $precedence || $in_bracket) {
// Precedence of operator is higher, push operator on stack
$stack->push($token);
$precedences->push($new_precedence);
$precedence = $new_precedence;
} else {
// Precedence is equal or lower, calculate result on stack
while ($new_precedence <= $precedence && $stack->count() > 1) {
$right = (float)$stack->pop();
$operator = $stack->pop();
$left = (float)$stack->pop();
$result = $this->calculate($operator, $left, $right);
$stack->push($result);
$precedence = $precedences->pop();
}
$stack->push($token);
$precedence = $new_precedence;
$precedences->push($new_precedence);
}
} elseif ($token === ')') {
// Need to calculate stack back to opening bracket
$_tokens = array();
$elem = $stack->pop();
while ($elem !== '(' && !$stack->isEmpty()) {
$_tokens[] = $elem;
$elem = $stack->pop();
}
// Get result within brackets recursive and push to stack
$stack->push($this->parseMath(array_reverse($_tokens)));
$in_bracket = false;
} else {
throw new ilException("Unrecognized token '$token'");
}
// $stack->debug();
}
// If one element is left on stack, we are done. Otherwise calculate
if ($stack->count() == 1) {
$result = $stack->pop();
return (ctype_digit((string)$result)) ? $result : number_format($result, self::N_DECIMALS, '.', "'");
} else {
while ($stack->count() >= 3) {
$right = $stack->pop();
$operator = $stack->pop();
$left = $stack->pop();
$stack->push($this->calculate($operator, $left, $right));
}
$result = $stack->pop();
return $result;
}
}

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

ilDclExpressionParser::substituteFieldValues ( array  $tokens)
protected

Given an array of tokens, replace each token that is a placeholder (e.g.

[[Field name]]) with it's value

Parameters
array$tokens
Returns
array

Definition at line 252 of file class.ilDclExpressionParser.php.

Referenced by calculateFunctions(), and parse().

{
$replaced = array();
foreach ($tokens as $token) {
if (strpos($token, '[[') === 0) {
$replaced[] = $this->substituteFieldValue($token);
} else {
$replaced[] = $token;
}
}
return $replaced;
}

+ Here is the caller graph for this function:

Field Documentation

ilDclExpressionParser::$cache_fields = array()
staticprotected

Definition at line 43 of file class.ilDclExpressionParser.php.

ilDclExpressionParser::$cache_math_function_tokens = array()
staticprotected

Definition at line 51 of file class.ilDclExpressionParser.php.

ilDclExpressionParser::$cache_math_tokens = array()
staticprotected

Definition at line 47 of file class.ilDclExpressionParser.php.

ilDclExpressionParser::$cache_tokens = array()
staticprotected

Definition at line 39 of file class.ilDclExpressionParser.php.

ilDclExpressionParser::$expression
protected

Definition at line 25 of file class.ilDclExpressionParser.php.

Referenced by __construct().

ilDclExpressionParser::$field
protected

Definition at line 21 of file class.ilDclExpressionParser.php.

Referenced by __construct().

ilDclExpressionParser::$functions
staticprotected
Initial value:
array(
'SUM',
'AVERAGE',
'MIN',
'MAX',
)

Definition at line 55 of file class.ilDclExpressionParser.php.

Referenced by getFunctions(), and isMathToken().

ilDclExpressionParser::$operators
staticprotected
Initial value:
array(
'+' => array( 'precedence' => 1 ),
'-' => array( 'precedence' => 1 ),
'*' => array( 'precedence' => 2 ),
'/' => array( 'precedence' => 2 ),
'^' => array( 'precedence' => 3 ),
)

Definition at line 29 of file class.ilDclExpressionParser.php.

Referenced by getOperators(), isMathToken(), and parseMath().

ilDclExpressionParser::$record
protected

Definition at line 17 of file class.ilDclExpressionParser.php.

Referenced by __construct().

const ilDclExpressionParser::N_DECIMALS = 1

Definition at line 11 of file class.ilDclExpressionParser.php.

const ilDclExpressionParser::SCIENTIFIC_NOTATION_LOWER = 0.000000001

Definition at line 13 of file class.ilDclExpressionParser.php.

const ilDclExpressionParser::SCIENTIFIC_NOTATION_UPPER = 1000000000000

Definition at line 12 of file class.ilDclExpressionParser.php.


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