Пример #1
0
 /**
  * @inheritdoc
  */
 public function parse(array $tokens)
 {
     $ast = new AbstractSyntaxTree();
     /** @var Token $token */
     foreach ($tokens as $token) {
         switch ($token->getType()) {
             case TokenTypes::T_EXPRESSION:
                 $ast->getCurrentNode()->addChild(new ExpressionNode($token->getValue()));
                 break;
             case TokenTypes::T_DIRECTIVE_OPEN:
                 if (!$ast->getCurrentNode()->isRoot()) {
                     $this->throwImproperlyNestedNodeException($token);
                 }
                 $childNode = new DirectiveNode();
                 $ast->getCurrentNode()->addChild($childNode);
                 $ast->setCurrentNode($childNode);
                 break;
             case TokenTypes::T_DIRECTIVE_CLOSE:
                 if (!$ast->getCurrentNode()->isDirective()) {
                     $this->throwUnopenedDelimiterException($token);
                 }
                 $ast->setCurrentNode($ast->getCurrentNode()->getParent());
                 break;
             case TokenTypes::T_DIRECTIVE_NAME:
                 $ast->getCurrentNode()->addChild(new DirectiveNameNode($token->getValue()));
                 break;
             case TokenTypes::T_SANITIZED_TAG_OPEN:
                 if (!$ast->getCurrentNode()->isRoot()) {
                     $this->throwImproperlyNestedNodeException($token);
                 }
                 $childNode = new SanitizedTagNode();
                 $ast->getCurrentNode()->addChild($childNode);
                 $ast->setCurrentNode($childNode);
                 break;
             case TokenTypes::T_SANITIZED_TAG_CLOSE:
                 if (!$ast->getCurrentNode()->isSanitizedTag()) {
                     $this->throwUnopenedDelimiterException($token);
                 }
                 $ast->setCurrentNode($ast->getCurrentNode()->getParent());
                 break;
             case TokenTypes::T_UNSANITIZED_TAG_OPEN:
                 if (!$ast->getCurrentNode()->isRoot()) {
                     $this->throwImproperlyNestedNodeException($token);
                 }
                 $childNode = new UnsanitizedTagNode();
                 $ast->getCurrentNode()->addChild($childNode);
                 $ast->setCurrentNode($childNode);
                 break;
             case TokenTypes::T_UNSANITIZED_TAG_CLOSE:
                 if (!$ast->getCurrentNode()->isUnsanitizedTag()) {
                     $this->throwUnopenedDelimiterException($token);
                 }
                 $ast->setCurrentNode($ast->getCurrentNode()->getParent());
                 break;
             case TokenTypes::T_COMMENT_OPEN:
                 if (!$ast->getCurrentNode()->isRoot()) {
                     $this->throwImproperlyNestedNodeException($token);
                 }
                 $childNode = new CommentNode();
                 $ast->getCurrentNode()->addChild($childNode);
                 $ast->setCurrentNode($childNode);
                 break;
             case TokenTypes::T_COMMENT_CLOSE:
                 if (!$ast->getCurrentNode()->isComment()) {
                     $this->throwUnopenedDelimiterException($token);
                 }
                 $ast->setCurrentNode($ast->getCurrentNode()->getParent());
                 break;
             case TokenTypes::T_PHP_TAG_OPEN:
                 $ast->getCurrentNode()->addChild(new ExpressionNode($token->getValue()));
                 break;
             case TokenTypes::T_PHP_TAG_CLOSE:
                 $ast->getCurrentNode()->addChild(new ExpressionNode($token->getValue()));
                 break;
             default:
                 throw new RuntimeException(sprintf('Unknown token type "%s" with value "%s" near line %d', $token->getType(), $token->getValue(), $token->getLine()));
         }
     }
     if (!$ast->getCurrentNode()->isRoot()) {
         throw new RuntimeException(sprintf("Expected close delimiter, found %s", $ast->getCurrentNode()->getValue()));
     }
     return $ast;
 }