Esempio n. 1
0
 /**
  * Parses the expression by using the ezcTemplateExpressionSourceToTstParser class.
  *
  * @param ezcTemplateCursor $cursor
  * @return bool
  */
 protected function parseCurrent(ezcTemplateCursor $cursor)
 {
     $name = $this->block->name;
     // handle closing block
     if ($this->block->isClosingBlock) {
         // skip whitespace and comments
         $this->findNextElement();
         if (!$cursor->match('}')) {
             throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_CURLY_BRACKET_CLOSE);
         }
         $el = new ezcTemplateIfConditionTstNode($this->parser->source, $this->startCursor, $cursor);
         $el->name = 'if';
         $el->isClosingBlock = true;
         $this->appendElement($el);
         return true;
     }
     $condition = null;
     $this->findNextElement();
     if ($name != 'else') {
         if (!$this->parseRequiredType('Expression', null, false)) {
             throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_EXPRESSION);
         }
         $condition = $this->lastParser->rootOperator;
         if ($condition instanceof ezcTemplateModifyingOperatorTstNode) {
             throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_MODIFYING_EXPRESSION_NOT_ALLOWED);
         }
         $this->findNextElement();
     }
     if (!$cursor->match('}')) {
         throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_CURLY_BRACKET_CLOSE);
     }
     $cb = new ezcTemplateConditionBodyTstNode($this->parser->source, $this->startCursor, $cursor);
     $cb->condition = $condition;
     $cb->name = $name;
     if ($name == 'if') {
         $el = new ezcTemplateIfConditionTstNode($this->parser->source, $this->startCursor, $cursor);
         $el->children[] = $cb;
         $el->name = 'if';
         $this->appendElement($el);
     } else {
         $this->appendElement($cb);
     }
     return true;
 }
Esempio n. 2
0
 /**
  * Parses the null type.
  *
  * @param ezcTemplateCursor $cursor
  * @return bool
  */
 protected function parseCurrent(ezcTemplateCursor $cursor)
 {
     if (!$cursor->atEnd()) {
         if ($cursor->match("null")) {
             $literal = new ezcTemplateLiteralTstNode($this->parser->source, $this->startCursor, $cursor);
             $literal->value = null;
             $this->element = $literal;
             $this->appendElement($literal);
             return true;
         }
     }
     return false;
 }
Esempio n. 3
0
 /**
  * Parses the expression by using the ezcTemplateExpressionSourceToTstParser class.
  *
  * @param ezcTemplateCursor $cursor
  * @return bool
  */
 protected function parseCurrent(ezcTemplateCursor $cursor)
 {
     $element = new ezcTemplateLoopTstNode($this->parser->source, $this->startCursor, $cursor, $this->block->name);
     if ($this->block->isClosingBlock) {
         $element->isClosingBlock = true;
     }
     $this->findNextElement();
     if (!$cursor->match("}")) {
         throw new ezcTemplateParserException($this->parser->source, $cursor, $cursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_CURLY_BRACKET_CLOSE);
     }
     $this->appendElement($element);
     return true;
 }
Esempio n. 4
0
 /**
  * Parses the expression by using the ezcTemplateExpressionSourceToTstParser class.
  *
  * @param ezcTemplateCursor $cursor
  * @return bool
  */
 protected function parseCurrent(ezcTemplateCursor $cursor)
 {
     if ($this->block->name == "charset") {
         $charset = new ezcTemplateCharsetTstNode($this->parser->source, $this->startCursor, $cursor);
         $this->findNextElement();
         if (!$this->parseOptionalType('String', null, false)) {
             throw new ezcTemplateSourceToTstParserException($this, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_STRING);
         }
         $charset->name = $this->lastParser->value;
         $this->findNextElement();
         if (!$cursor->match("}")) {
             throw new ezcTemplateParserException($this->parser->source, $cursor, $cursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_CURLY_BRACKET_CLOSE);
         }
         $this->appendElement($charset);
         return true;
     }
     return false;
 }
Esempio n. 5
0
 /**
  * Parses the variable types by looking for a dollar sign followed by an
  * identifier. The identifier is parsed by using ezcTemplateIdentifierSourceToTstParser.
  *
  * @param ezcTemplateCursor $cursor
  * @return bool
  */
 protected function parseCurrent(ezcTemplateCursor $cursor)
 {
     if (!$cursor->atEnd()) {
         if ($cursor->match('$')) {
             if ($cursor->current() == '#') {
                 throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_INVALID_VARIABLE_NAME, ezcTemplateSourceToTstErrorMessages::LNG_INVALID_NAMESPACE_ROOT_MARKER);
             }
             if ($cursor->current() == ':') {
                 throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_INVALID_VARIABLE_NAME, ezcTemplateSourceToTstErrorMessages::LNG_INVALID_NAMESPACE_MARKER);
             }
             if (!$this->parseRequiredType('Identifier', null, false)) {
                 throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_INVALID_VARIABLE_NAME, ezcTemplateSourceToTstErrorMessages::MSG_INVALID_IDENTIFIER);
                 return false;
             }
             $this->variableName = $this->lastParser->identifierName;
             $variable = new ezcTemplateVariableTstNode($this->parser->source, $this->startCursor, $cursor);
             $variable->name = $this->variableName;
             $this->element = $variable;
             $this->appendElement($variable);
             return true;
         }
     }
     return false;
 }
Esempio n. 6
0
 /**
  * Parses the expression by using the ezcTemplateExpressionSourceToTstParser class.
  *
  * @param ezcTemplateCursor $cursor
  * @return bool
  */
 protected function parseCurrent(ezcTemplateCursor $cursor)
 {
     // Disable caching.
     // return false;
     if ($cursor->match("dynamic")) {
         $cacheNode = new ezcTemplateDynamicBlockTstNode($this->parser->source, $this->startCursor, $cursor);
         if ($this->block->isClosingBlock) {
             $cacheNode->isClosingBlock = true;
         }
         $this->appendElement($cacheNode);
         $this->findNextElement($cursor);
         if (!$cursor->match("}")) {
             throw new ezcTemplateParserException($this->parser->source, $cursor, $cursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_CURLY_BRACKET_CLOSE);
         }
         return true;
     }
     $cacheNode = null;
     if ($cursor->match("cache_template")) {
         $this->parser->hasCacheBlocks = true;
         $cacheNode = new ezcTemplateCacheTstNode($this->parser->source, $this->startCursor, $cursor);
         $cacheNode->type = ezcTemplateCacheTstNode::TYPE_CACHE_TEMPLATE;
     } elseif ($cursor->match("cache_block")) {
         $this->parser->hasCacheBlocks = true;
         $cacheNode = new ezcTemplateCacheBlockTstNode($this->parser->source, $this->startCursor, $cursor);
         // $cacheNode->type = ezcTemplateCacheTstNode::TYPE_CACHE_BLOCK;
         if ($this->block->isClosingBlock) {
             $cacheNode->isClosingBlock = true;
             // Set closing block.
             $this->appendElement($cacheNode);
             $this->findNextElement($cursor);
             if (!$cursor->match("}")) {
                 throw new ezcTemplateParserException($this->parser->source, $cursor, $cursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_CURLY_BRACKET_CLOSE);
             }
             return true;
         }
     } else {
         return false;
     }
     // We do have an opening cache_block or cache_template.
     $this->findNextElement($cursor);
     while ($matches = $cursor->pregMatchComplete("#^([a-zA-Z_][a-zA-Z0-9_-]*)(?:[^a-zA-Z])#i")) {
         $name = $matches[1][0];
         $cursor->advance(strlen($name));
         $this->findNextElement($cursor);
         if ($name == "keys") {
             do {
                 $this->findNextElement($cursor);
                 if (!$this->parseOptionalType("Expression", $this->currentCursor, false)) {
                     throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_VARIABLE);
                 }
                 $cacheNode->keys[] = $this->lastParser->children[0];
                 $this->findNextElement($cursor);
             } while ($cursor->match(","));
             // $this->parser->template->configuration->cacheSystem->appendCacheKeys( $values );
         } elseif ($name == "ttl") {
             // The parameter has an expression.
             if (!$this->parseOptionalType('Expression', null, false)) {
                 throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_EXPRESSION);
             }
             if ($this->lastParser->rootOperator instanceof ezcTemplateModifyingOperatorTstNode) {
                 throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_MODIFYING_EXPRESSION_NOT_ALLOWED);
             }
             // Append the parameter to the "namedParameters" array.
             $cacheNode->ttl = $this->lastParser->rootOperator;
         } else {
             throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, "Unknown keyword: " . $name);
         }
     }
     $this->appendElement($cacheNode);
     $this->findNextElement($cursor);
     if (!$cursor->match("}")) {
         throw new ezcTemplateParserException($this->parser->source, $cursor, $cursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_CURLY_BRACKET_CLOSE);
     }
     return true;
 }
Esempio n. 7
0
 /**
  * Parses the array types by looking for 'array(...)' and then using the
  * generic expression parser (ezcTemplateExpressionSourceToTstParser) to fetch the
  * keys and values.
  *
  * @param ezcTemplateCursor $cursor
  * @return bool
  */
 protected function parseCurrent(ezcTemplateCursor $cursor)
 {
     // skip whitespace and comments
     if (!$this->findNextElement()) {
         return false;
     }
     $name = $cursor->pregMatch("#^array[^\\w]#i", false);
     if ($name === false) {
         return false;
     }
     $lower = strtolower($name);
     if ($name !== $lower) {
         $this->findNonLowercase();
         throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_ARRAY_NOT_LOWERCASE);
     }
     $cursor->advance(5);
     // skip whitespace and comments
     $this->findNextElement();
     if (!$cursor->match('(')) {
         throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_ROUND_BRACKET_OPEN);
     }
     $currentArray = array();
     $currentKeys = array();
     $expectItem = true;
     $elementNumber = 0;
     while (true) {
         // skip whitespace and comments
         if (!$this->findNextElement()) {
             throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_ROUND_BRACKET_CLOSE);
         }
         if ($cursor->current() == ')') {
             $cursor->advance();
             $array = new ezcTemplateLiteralArrayTstNode($this->parser->source, $this->startCursor, $cursor);
             $array->keys = $currentKeys;
             $array->value = $currentArray;
             $this->element = $array;
             $this->appendElement($array);
             return true;
         }
         if (!$expectItem) {
             throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_ROUND_BRACKET_CLOSE_OR_COMMA);
         }
         // Check for type
         if (!$expectItem || !$this->parseRequiredType('Expression')) {
             throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_LITERAL);
         }
         $this->findNextElement();
         if ($cursor->match('=>')) {
             // Found the array key. Store it, and continue with the search for the value.
             $currentKeys[$elementNumber] = $this->lastParser->rootOperator;
             $this->findNextElement();
             // We have the key => value syntax so we need to find the value
             if (!$this->parseRequiredType('Expression')) {
                 throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_LITERAL);
             }
             // Store the value.
             $currentArray[$elementNumber] = $this->lastParser->rootOperator;
             $elementNumber++;
         } else {
             // Store the value.
             $currentArray[$elementNumber] = $this->lastParser->rootOperator;
             $elementNumber++;
         }
         if ($this->lastParser->rootOperator instanceof ezcTemplateModifyingOperatorTstNode) {
             throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_MODIFYING_EXPRESSION_NOT_ALLOWED);
         }
         $this->findNextElement();
         // We allow a comma after the key/value even if there are no more
         // entries. This is compatible with PHP syntax.
         if ($cursor->match(',')) {
             $this->findNextElement();
             $expectItem = true;
         } else {
             $expectItem = false;
         }
     }
 }
Esempio n. 8
0
 /**
  * Parses the expression by using the ezcTemplateExpressionSourceToTstParser class.
  *
  * @param ezcTemplateCursor $cursor
  * @return bool
  */
 protected function parseCurrent(ezcTemplateCursor $cursor)
 {
     $el = new ezcTemplateTranslationTstNode($this->parser->source, $this->startCursor, $cursor);
     $this->findNextElement();
     if (!$this->parseRequiredType('String', null, false)) {
         throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_STRING);
     }
     $el->string = $this->lastParser->element;
     // empty keys and values before the loop, so that multiple vars statements can work
     $currentKeys = $currentArray = array();
     $foundContext = $foundComment = false;
     $elementNr = 0;
     // the loop that parses context/comment/vars
     do {
         $foundSomething = false;
         $this->findNextElement();
         // Check if we have a context
         if ($cursor->match('context')) {
             if ($foundContext) {
                 throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->lastCursor, ezcTemplateSourceToTstErrorMessages::MSG_CONTEXT_DUPLICATE);
             }
             $this->findNextElement();
             if (!$this->parseRequiredType('String', null, false)) {
                 throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_STRING);
             }
             $el->context = $this->lastParser->element;
             $foundSomething = $foundContext = true;
         }
         // Check if we have a comment
         if ($cursor->match('comment')) {
             if ($foundComment) {
                 throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_COMMENT_DUPLICATE);
             }
             $this->findNextElement();
             if (!$this->parseRequiredType('String', null, false)) {
                 throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_STRING);
             }
             $el->comment = $this->lastParser->element;
             $foundSomething = $foundComment = true;
         }
         // Check the variables.
         if ($cursor->match('vars')) {
             do {
                 // save the cursor so that we can restore it to retry a different sequence
                 $saveCursor = clone $cursor;
                 // try to parse string => expression
                 if ($elements = $this->parseSequence(array(array('type' => 'String'), array('type' => 'Character', 'args' => '=>'), array('type' => 'Expression')))) {
                     $currentKeys[$elementNr] = $elements[0];
                     $currentArray[$elementNr] = $elements[1];
                     $elementNr++;
                     continue;
                 }
                 // restore the cursor if not found
                 $this->currentCursor = $saveCursor;
                 $cursor = $saveCursor;
                 // try to parse integer => expression
                 if ($elements = $this->parseSequence(array(array('type' => 'Integer'), array('type' => 'Character', 'args' => '=>'), array('type' => 'Expression')))) {
                     $currentKeys[$elementNr] = $elements[0];
                     $currentArray[$elementNr] = $elements[1];
                     $elementNr++;
                     continue;
                 }
                 // restore the cursor if not found
                 $this->currentCursor = $saveCursor;
                 $cursor = $saveCursor;
                 if (!$this->parseRequiredType('Expression', null, false)) {
                     throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, "Expecting a valid variable definition (String => Expression; Integer => Expression; or Expression).");
                 }
                 $expression = $this->lastParser->rootOperator;
                 unset($currentKeys[$elementNr]);
                 $currentArray[$elementNr] = $expression;
                 $elementNr++;
             } while ($cursor->match(','));
             $array = new ezcTemplateLiteralArrayTstNode($this->parser->source, $this->startCursor, $cursor);
             $array->keys = $currentKeys;
             $array->value = $currentArray;
             $el->variables = $array;
             $foundSomething = true;
         }
     } while ($foundSomething);
     if (!$this->parentParser->atEnd($cursor, null, false)) {
         throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_CURLY_BRACKET_CLOSE);
     }
     $cursor->advance();
     $this->appendElement($el);
     return true;
 }
Esempio n. 9
0
 /**
  * Parses the block by using sub parser, the conditions are:
  * - The block contains {*...*} in which case ezcTemplateDocCommentSourceToTstParser is
  *   used.
  * - The block contains a generic expression in which case
  *   ezcTemplateExpressionBlockSourceToTstParser is used.
  *
  * @param ezcTemplateCursor $cursor
  * @return bool
  */
 protected function parseCurrent(ezcTemplateCursor $cursor)
 {
     // Check for doc comments which look like {*...*}
     if (!$cursor->atEnd() && $cursor->current() == '*') {
         // got a doc comment block
         if (!$this->parseRequiredType('DocComment', $this->startCursor)) {
             throw new ezcTemplateParserException($this->parser->source, $cursor, $cursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_CLOSING_BLOCK_COMMENT);
         }
         return true;
     }
     // $cursor object in $block will be updated as the parser continues
     $this->block = new ezcTemplateBlockTstNode($this->parser->source, $this->startCursor, $cursor);
     $this->findNextElement();
     // Test for and ending control structure.
     if (!$cursor->atEnd() && $cursor->current() == '/') {
         // got a closing block marker
         $this->block->isClosingBlock = true;
         $closingCursor = clone $cursor;
         $this->block->closingCursor = $closingCursor;
         $cursor->advance(1);
         $this->findNextElement();
         // Check for internal blocks which are known to not support closing markers.
         // foreach|while|if|switch|case|default|delimiter|literal|dynamic|cache_template
         $matches = $cursor->pregMatchComplete("#^(tr|tr_context|elseif|else|include|return|break|continue|skip|increment|decrement|reset|once|var|use|cycle|ldelim|rdelim)(?:[^a-zA-Z0-9_])#");
         if ($matches !== false) {
             throw new ezcTemplateParserException($this->parser->source, $this->block->closingCursor, $this->block->closingCursor, ezcTemplateSourceToTstErrorMessages::MSG_CLOSING_BLOCK_NOW_ALLOWED);
         }
     }
     // Try to parse a control structure
     $controlStructureParser = new ezcTemplateControlStructureSourceToTstParser($this->parser, $this, null);
     $controlStructureParser->block = $this->block;
     if ($this->parseOptionalType($controlStructureParser, null, false)) {
         if ($this->lastParser->status == self::PARSE_PARTIAL_SUCCESS) {
             return false;
         }
         $this->mergeElements($this->lastParser);
         return true;
     }
     // Try to parse a literal block
     if ($this->parseOptionalType('LiteralBlock', $this->startCursor)) {
         return true;
     }
     // Try to parse a declaration block
     if ($this->parseOptionalType('DeclarationBlock', $this->startCursor)) {
         return true;
     }
     // Try to parse as an expression, if this fails the normal block parser
     // is tried.
     if ($this->parseOptionalType('ExpressionBlock', $this->startCursor)) {
         if (!$this->currentCursor->match('}')) {
             if ($this->currentCursor->match('[', false)) {
                 throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_UNEXPECTED_SQUARE_BRACKET_OPEN);
             }
             throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_CURLY_BRACKET_CLOSE);
         }
         return true;
     }
     if ($cursor->match('}')) {
         // Empty block found, this is allowed but the returned block
         // will be ignored when compiling
         $this->elements[] = $this->lastParser->block;
         return true;
     }
     // Parse the {ldelim} and {rdelim}
     $matches = $this->currentCursor->pregMatchComplete("#^(ldelim|rdelim)(?:[^a-zA-Z0-9_])#");
     $name = $matches[1][0];
     $ldelim = $name == 'ldelim' ? true : false;
     $rdelim = $name == 'rdelim' ? true : false;
     if ($ldelim || $rdelim) {
         $this->currentCursor->advance(strlen($name));
         $this->findNextElement();
         if (!$this->currentCursor->match("}")) {
             throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_CURLY_BRACKET_CLOSE);
         }
         $text = new ezcTemplateTextBlockTstNode($this->parser->source, $this->startCursor, $this->endCursor);
         $text->text = $ldelim ? "{" : "}";
         $this->appendElement($text);
         return true;
     }
     // Parse the cache blocks.
     $cacheParser = new ezcTemplateCacheSourceToTstParser($this->parser, $this, null);
     $cacheParser->block = $this->block;
     if ($this->parseOptionalType($cacheParser, null)) {
         return true;
     }
     // Try to parse custom blocks, these are pluggable and follows a generic syntax.
     $customBlockParser = new ezcTemplateCustomBlockSourceToTstParser($this->parser, $this, null);
     $customBlockParser->block = $this->block;
     if ($this->parseOptionalType($customBlockParser, null)) {
         return true;
     }
     $matches = $cursor->pregMatchComplete("#^([a-zA-Z_][a-zA-Z0-9_-]*)(?:[^a-zA-Z])#i");
     throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, sprintf(ezcTemplateSourceToTstErrorMessages::MSG_UNKNOWN_BLOCK, $matches[1][0]));
 }
Esempio n. 10
0
 /**
  * Parses the expression by using the ezcTemplateExpressionSourceToTstParser class.
  *
  * @param ezcTemplateCursor $cursor
  * @return bool
  */
 protected function parseCurrent(ezcTemplateCursor $cursor)
 {
     $rawBlock = false;
     if ($cursor->match("raw")) {
         $rawBlock = true;
         $this->findNextElement();
     }
     // $cursor will be update as the parser continues
     if ($this->startBracket == '(') {
         // This is a parenthesis so we use a different node type
         $this->block = new ezcTemplateParenthesisTstNode($this->parser->source, $this->startCursor, $cursor);
         $this->block->startBracket = $this->startBracket;
         $this->block->endBracket = $this->endBracket;
     } else {
         $this->block = new ezcTemplateOutputBlockTstNode($this->parser->source, $this->startCursor, $cursor);
         $this->block->isRaw = $rawBlock;
         $this->block->startBracket = $this->startBracket;
         $this->block->endBracket = $this->endBracket;
     }
     // skip whitespace and comments
     if (!$this->findNextElement()) {
         return false;
     }
     $allowIdentifier = false;
     // Check for expression, the parser will call atEnd() of this class to
     // check for end of the expression.
     $expressionParser = new ezcTemplateExpressionSourceToTstParser($this->parser, $this, null);
     $expressionParser->setAllCursors($cursor);
     $expressionParser->startCursor = clone $cursor;
     $expressionParser->allowEmptyExpressions = true;
     if (!$this->parseRequiredType($expressionParser, $this->startCursor, false)) {
         return false;
     }
     $this->findNextElement();
     $rootOperator = $this->lastParser->currentOperator;
     if ($rootOperator instanceof ezcTemplateOperatorTstNode) {
         $rootOperator = $rootOperator->getRoot();
     }
     // If there is no root operator the block is empty, change the block type.
     if ($rootOperator === null) {
         $this->block = new ezcTemplateEmptyBlockTstNode($this->parser->source, clone $this->startCursor, $cursor);
         $this->appendElement($this->block);
         return true;
     }
     // Change the block type if the top-most operator is a modifiying operator.
     if ($rootOperator instanceof ezcTemplateModifyingOperatorTstNode) {
         if ($rawBlock) {
             throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_ASSIGNMENT_NOT_ALLOWED);
         }
         // @todo if the parser block is a parenthesis it is not allowed to have modifying nodes
         $oldBlock = $this->block;
         $this->block = new ezcTemplateModifyingBlockTstNode($this->parser->source, clone $this->startCursor, $cursor);
         $this->block->startBracket = $this->startBracket;
         $this->block->endBracket = $this->endBracket;
         $this->block->children = $oldBlock->children;
     }
     $this->block->expressionRoot = $rootOperator;
     $this->block->children = array($rootOperator);
     $this->appendElement($this->block);
     return true;
 }
Esempio n. 11
0
 /**
  * Parse assignment operator
  *
  * @param ezcTemplateCursor $cursor 
  * @return bool
  */
 protected function parseAssignmentOperator($cursor)
 {
     if ($cursor->match("=")) {
         $function = "ezcTemplateAssignmentOperatorTstNode";
         $operator = new $function($this->parser->source, clone $this->lastCursor, $cursor);
         $this->checkForValidOperator($this->currentOperator, $operator, $cursor);
         $this->currentOperator = $this->parser->handleOperatorPrecedence($this->currentOperator, $operator);
         return true;
     }
     return false;
 }
Esempio n. 12
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. 13
0
 /**
  * Parses the expression by using the ezcTemplateExpressionSourceToTstParser class.
  *
  * @param ezcTemplateCursor $cursor
  * @return bool
  */
 protected function parseCurrent(ezcTemplateCursor $cursor)
 {
     $name = $this->block->name;
     // handle closing block
     if ($this->block->isClosingBlock) {
         // skip whitespace and comments
         $this->findNextElement();
         if (!$cursor->match('}')) {
             throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_CURLY_BRACKET_CLOSE);
         }
         if ($name == 'switch') {
             $sw = new ezcTemplateSwitchTstNode($this->parser->source, $this->startCursor, $cursor);
         } else {
             // Tricky: Skip the spaces and new lines. Next element should be an case, or default.
             // $this->findNextElement();
             $sw = new ezcTemplateCaseTstNode($this->parser->source, $this->startCursor, $cursor);
             $sw->name = $name;
             // Set the name to either 'case' or 'default'.
         }
         // $el->name = 'switch';
         $sw->isClosingBlock = true;
         $this->appendElement($sw);
         return true;
     }
     if ($name == 'switch') {
         $this->findNextElement();
         if (!$this->parseRequiredType('Expression', null, false)) {
             throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_EXPRESSION);
         }
         if ($this->lastParser->rootOperator instanceof ezcTemplateModifyingOperatorTstNode) {
             throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_MODIFYING_EXPRESSION_NOT_ALLOWED);
         }
         $this->findNextElement();
         if (!$cursor->match('}')) {
             throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_CURLY_BRACKET_CLOSE);
         }
         // Tricky: Skip the spaces and new lines. Next element should be an case, or default.
         // $this->findNextElement();
         $sw = new ezcTemplateSwitchTstNode($this->parser->source, $this->startCursor, $cursor);
         $sw->condition = $this->lastParser->rootOperator;
         $this->appendElement($sw);
         return true;
     } elseif ($name == 'case') {
         $case = new ezcTemplateCaseTstNode($this->parser->source, $this->startCursor, $cursor);
         $case->name = $name;
         // Set the name to 'case'
         do {
             $this->findNextElement();
             if (!$this->parseRequiredType('Literal', null, false)) {
                 throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_LITERAL);
             }
             $case->conditions[] = $this->lastParser->element;
             $this->findNextElement();
         } while ($cursor->match(','));
         if (!$cursor->match('}')) {
             throw new ezcTemplateParserException($this->parser->source, $this->startCursor, $this->currentCursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_CURLY_BRACKET_CLOSE);
         }
         // Tricky: Skip the spaces and new lines. Next element should be an case, or default.
         $this->findNextElement();
         $this->appendElement($case);
         return true;
     } elseif ($name == 'default') {
         $case = new ezcTemplateCaseTstNode($this->parser->source, $this->startCursor, $cursor);
         $case->name = $name;
         // Set the name to 'default'
         $case->conditions = null;
         $this->findNextElement();
         if (!$cursor->match('}')) {
             throw new ezcTemplateSourceToTstParserException($this, $cursor, ezcTemplateSourceToTstErrorMessages::MSG_EXPECT_CURLY_BRACKET_CLOSE);
         }
         // Tricky: Skip the spaces and new lines. Next element should be an case, or default.
         $this->findNextElement();
         $this->appendElement($case);
         return true;
     }
 }
Esempio n. 14
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;
 }