public static function parse(Parser $parser, TokensList $list, array $options = array())
{
$ret = new CaseExpression();
/**
* State of parser
*
* @var int $parser
*/
$state = 0;
/**
* Syntax type (type 0 or type 1)
*
* @var int $type
*/
$type = 0;
++$list->idx;
// Skip 'CASE'
for (; $list->idx < $list->count; ++$list->idx) {
/**
* Token parsed at this moment.
*
* @var Token $token
*/
$token = $list->tokens[$list->idx];
// Skipping whitespaces and comments.
if ($token->type === Token::TYPE_WHITESPACE || $token->type === Token::TYPE_COMMENT) {
continue;
}
if ($state === 0) {
if ($token->type === Token::TYPE_KEYWORD && $token->value === 'WHEN') {
++$list->idx;
// Skip 'WHEN'
$new_condition = Condition::parse($parser, $list);
$type = 1;
$state = 1;
$ret->conditions[] = $new_condition;
} elseif ($token->type === Token::TYPE_KEYWORD && $token->value === 'ELSE') {
++$list->idx;
// Skip 'ELSE'
$ret->else_result = Expression::parse($parser, $list);
$state = 0;
// last clause of CASE expression
} elseif ($token->type === Token::TYPE_KEYWORD && ($token->value === 'END' || $token->value === 'end')) {
$state = 3;
// end of CASE expression
++$list->idx;
break;
} elseif ($token->type === Token::TYPE_KEYWORD) {
$parser->error(__('Unexpected keyword.'), $token);
break;
} else {
$ret->value = Expression::parse($parser, $list);
$type = 0;
$state = 1;
}
} elseif ($state === 1) {
if ($type === 0) {
if ($token->type === Token::TYPE_KEYWORD && $token->value === 'WHEN') {
++$list->idx;
// Skip 'WHEN'
$new_value = Expression::parse($parser, $list);
$state = 2;
$ret->compare_values[] = $new_value;
} elseif ($token->type === Token::TYPE_KEYWORD && $token->value === 'ELSE') {
++$list->idx;
// Skip 'ELSE'
$ret->else_result = Expression::parse($parser, $list);
$state = 0;
// last clause of CASE expression
} elseif ($token->type === Token::TYPE_KEYWORD && ($token->value === 'END' || $token->value === 'end')) {
$state = 3;
// end of CASE expression
++$list->idx;
break;
} elseif ($token->type === Token::TYPE_KEYWORD) {
$parser->error(__('Unexpected keyword.'), $token);
break;
}
} else {
if ($token->type === Token::TYPE_KEYWORD && $token->value === 'THEN') {
++$list->idx;
// Skip 'THEN'
$new_result = Expression::parse($parser, $list);
$state = 0;
$ret->results[] = $new_result;
} elseif ($token->type === Token::TYPE_KEYWORD) {
$parser->error(__('Unexpected keyword.'), $token);
break;
}
}
} elseif ($state === 2) {
if ($type === 0) {
if ($token->type === Token::TYPE_KEYWORD && $token->value === 'THEN') {
++$list->idx;
// Skip 'THEN'
$new_result = Expression::parse($parser, $list);
$ret->results[] = $new_result;
$state = 1;
} elseif ($token->type === Token::TYPE_KEYWORD) {
$parser->error(__('Unexpected keyword.'), $token);
break;
}
}
}
}
if ($state !== 3) {
$parser->error(__('Unexpected end of CASE expression'), $list->tokens[$list->idx - 1]);
}
--$list->idx;
return $ret;
}