Esempio n. 1
0
 /**
  * Parse a parameter
  *
  * @param ezcTemplateCursor $cursor
  * @return bool
  */
 protected function parseParameter($cursor)
 {
     // Without this, the expression parser keeps on reading.
     if ($cursor->match(')', false)) {
         return false;
     }
     $this->readingParameter = true;
     $startCursor = clone $cursor;
     $namedParameter = $cursor->pregMatch("#^[a-zA-Z_][a-zA-Z0-9_]*#");
     if ($namedParameter !== false) {
         $this->findNextElement();
         if (!$cursor->match("=")) {
             $namedParameter = false;
         }
     }
     if ($namedParameter === false) {
         $cursor->copy($startCursor);
     }
     // Check for expression, the parser will call self::atEnd() to check for end of expression.
     $expressionStartCursor = clone $cursor;
     $expressionParser = new ezcTemplateExpressionSourceToTstParser($this->parser, $this, null);
     $expressionParser->allowIdentifier = true;
     if (!$this->parseRequiredType($expressionParser) || $this->lastParser->currentOperator === null) {
         return false;
     }
     $rootOperator = $this->lastParser->currentOperator;
     if ($rootOperator instanceof ezcTemplateOperatorTstNode) {
         $rootOperator = $rootOperator->getRoot();
     }
     if ($rootOperator instanceof ezcTemplateModifyingOperatorTstNode) {
         throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, sprintf(ezcTemplateSourceToTstErrorMessages::MSG_PARAMETER_CANNOT_BE_MODIFYING_BLOCK, $this->parameterCount));
     }
     if ($namedParameter !== false) {
         if (isset($this->functionCall->parameters[$namedParameter])) {
             throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, sprintf(ezcTemplateSourceToTstErrorMessages::MSG_NAMED_PARAMETER_ALREADY_ASSIGNED, $namedParameter));
         }
         $this->functionCall->parameters[$namedParameter] = $rootOperator;
     } else {
         $this->functionCall->appendParameter($rootOperator);
     }
     $this->readingParameter = false;
     return true;
 }
Esempio n. 2
0
 /**
  * Parse operator
  *
  * @param ezcTemplateCursor $cursor 
  * @param bool $canDoAssignment
  * @return bool
  */
 protected function parseOperator($cursor, $canDoAssignment = true)
 {
     // Try som generic operators
     $operator = null;
     // This will contain the name of the operator if it is found.
     $operatorName = false;
     $operatorSymbols = array(array(3, array('===', '!==')), array(2, array('==', '!=', '<=', '>=', '&&', '||', '+=', '-=', '*=', '/=', '.=', '%=', '..', '=>')), array(1, array('+', '-', '.', '*', '/', '%', '<', '>', '=')));
     foreach ($operatorSymbols as $symbolEntry) {
         $chars = $cursor->current($symbolEntry[0]);
         if (in_array($chars, $symbolEntry[1])) {
             $operatorName = $chars;
             break;
         }
     }
     if ($operatorName !== false && $operatorName == "=>") {
         return false;
     }
     // Cannot do an assignment right now.
     if ($operatorName == "=" && !$canDoAssignment) {
         return false;
     }
     if ($operatorName !== false) {
         $operatorStartCursor = clone $cursor;
         $cursor->advance(strlen($operatorName));
         $operatorMap = array('+' => 'PlusOperator', '-' => 'MinusOperator', '.' => 'ConcatOperator', '*' => 'MultiplicationOperator', '/' => 'DivisionOperator', '%' => 'ModuloOperator', '==' => 'EqualOperator', '!=' => 'NotEqualOperator', '===' => 'IdenticalOperator', '!==' => 'NotIdenticalOperator', '<' => 'LessThanOperator', '>' => 'GreaterThanOperator', '<=' => 'LessEqualOperator', '>=' => 'GreaterEqualOperator', '&&' => 'LogicalAndOperator', '||' => 'LogicalOrOperator', '=' => 'AssignmentOperator', '+=' => 'PlusAssignmentOperator', '-=' => 'MinusAssignmentOperator', '*=' => 'MultiplicationAssignmentOperator', '/=' => 'DivisionAssignmentOperator', '.=' => 'ConcatAssignmentOperator', '%=' => 'ModuloAssignmentOperator', '..' => 'ArrayRangeOperator');
         $requestedName = $operatorName;
         $operatorName = $operatorMap[$operatorName];
         $function = "ezcTemplate" . $operatorName . "TstNode";
         $operator = new $function($this->parser->source, clone $this->lastCursor, $cursor);
         // If the min precedence has been reached we immediately stop parsing
         // and return a successful parse result
         if ($this->minPrecedence !== false && $operator->precedence < $this->minPrecedence) {
             $cursor->copy($operatorStartCursor);
             return $operatorName;
         }
         $this->checkForValidOperator($this->currentOperator, $operator, $operatorStartCursor);
         $this->currentOperator = $this->parser->handleOperatorPrecedence($this->currentOperator, $operator);
         $this->lastCursor->copy($cursor);
         return $operatorName;
     }
     return false;
 }
Esempio n. 3
0
 /**
  * Parses the literal by using the ezcTemplateLiteralParser class.
  *
  * @param ezcTemplateCursor $cursor
  * @return bool
  */
 protected function parseCurrent(ezcTemplateCursor $cursor)
 {
     // $cursor will be update as the parser continues
     $this->block = new ezcTemplateLiteralBlockTstNode($this->parser->source, clone $this->startCursor, $cursor);
     // skip whitespace and comments
     if (!$this->findNextElement()) {
         return false;
     }
     $hasClosingMarker = $cursor->current() == '/';
     if ($hasClosingMarker) {
         $closingCursor = clone $cursor;
         $cursor->advance();
         $this->findNextElement();
     }
     $matches = $cursor->pregMatchComplete("#^(literal)(?:[^a-zA-Z0-9_])#");
     if ($matches === false) {
         return false;
     }
     $cursor->advance(strlen($matches[1][0]));
     // skip whitespace and comments
     if (!$this->findNextElement()) {
         return false;
     }
     // Assume end of first {literal} block
     if (!$cursor->match("}")) {
         throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $cursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_CURLY_BRACKET_CLOSE);
     }
     if ($hasClosingMarker) {
         throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $cursor, "Found closing block {/literal} without an opening block.");
     }
     $literalTextCursor = clone $cursor;
     // Start searching for ending literal block.
     while (!$cursor->atEnd()) {
         // Find the next block
         $tagPos = $cursor->findPosition("{");
         if ($tagPos === false) {
             return false;
         }
         $tagCursor = clone $cursor;
         $tagCursor->gotoPosition($tagPos - 1);
         if ($tagCursor->current() == "\\") {
             // This means the tag is escaped and should be treated as text.
             $cursor->copy($tagCursor);
             $cursor->advance(2);
             unset($tagCursor);
             continue;
         }
         // Reached a block {...}
         $cursor->gotoPosition($tagPos);
         $literalTextEndCursor = clone $cursor;
         $cursor->advance();
         $continue = false;
         while (!$cursor->atEnd()) {
             // skip whitespace and comments
             if (!$this->findNextElement()) {
                 return false;
             }
             // Check for end, if not continue search
             if (!$cursor->match('/literal')) {
                 $continue = true;
                 break;
             }
             // skip whitespace and comments
             if (!$this->findNextElement()) {
                 return false;
             }
             if ($cursor->current() == '}') {
                 $this->block->textStartCursor = $literalTextCursor;
                 $this->block->textEndCursor = $literalTextEndCursor;
                 $cursor->advance();
                 $this->block->endCursor = clone $cursor;
                 // Make sure the text is extracted now that the cursor are correct
                 $this->block->storeText();
                 $this->appendElement($this->block);
                 return true;
             }
         }
         if ($continue) {
             continue;
         }
     }
     return false;
 }