vendor/twig-extensions/lib/Twig/Extensions/SimpleTokenParser.php
changeset 0 7f95f8617b0b
equal deleted inserted replaced
-1:000000000000 0:7f95f8617b0b
       
     1 <?php
       
     2 
       
     3 /*
       
     4  * This file is part of Twig.
       
     5  *
       
     6  * (c) 2010 Fabien Potencier
       
     7  *
       
     8  * For the full copyright and license information, please view the LICENSE
       
     9  * file that was distributed with this source code.
       
    10  */
       
    11 abstract class Twig_Extensions_SimpleTokenParser extends Twig_TokenParser
       
    12 {
       
    13     /**
       
    14      * Parses a token and returns a node.
       
    15      *
       
    16      * @param Twig_Token $token A Twig_Token instance
       
    17      *
       
    18      * @return Twig_NodeInterface A Twig_NodeInterface instance
       
    19      */
       
    20     public function parse(Twig_Token $token)
       
    21     {
       
    22         $grammar = $this->getGrammar();
       
    23         if (!is_object($grammar)) {
       
    24             $grammar = self::parseGrammar($grammar);
       
    25         }
       
    26 
       
    27         $grammar->setParser($this->parser);
       
    28         $values = $grammar->parse($token);
       
    29 
       
    30         return $this->getNode($values, $token->getLine());
       
    31     }
       
    32 
       
    33     /**
       
    34      * Gets the grammar as an object or as a string.
       
    35      *
       
    36      * @return string|Twig_Extensions_Grammar A Twig_Extensions_Grammar instance or a string
       
    37      */
       
    38     abstract protected function getGrammar();
       
    39 
       
    40     /**
       
    41      * Gets the nodes based on the parsed values.
       
    42      *
       
    43      * @param array   $values An array of values
       
    44      * @param integer $line   The parser line
       
    45      */
       
    46     abstract protected function getNode(array $values, $line);
       
    47 
       
    48     protected function getAttribute($node, $attribute, $arguments = array(), $type = Twig_Node_Expression_GetAttr::TYPE_ANY, $line = -1)
       
    49     {
       
    50         return new Twig_Node_Expression_GetAttr(
       
    51             $node instanceof Twig_NodeInterface ? $node : new Twig_Node_Expression_Name($node, $line),
       
    52             $attribute instanceof Twig_NodeInterface ? $attribute : new Twig_Node_Expression_Constant($attribute, $line),
       
    53             $arguments instanceof Twig_NodeInterface ? $arguments : new Twig_Node($arguments),
       
    54             $type,
       
    55             $line
       
    56         );
       
    57     }
       
    58 
       
    59     protected function call($node, $attribute, $arguments = array(), $line = -1)
       
    60     {
       
    61         return $this->getAttribute($node, $attribute, $arguments, Twig_Node_Expression_GetAttr::TYPE_METHOD, $line);
       
    62     }
       
    63 
       
    64     protected function markAsSafe(Twig_NodeInterface $node, $line = -1)
       
    65     {
       
    66         return new Twig_Node_Expression_Filter(
       
    67             $node,
       
    68             new Twig_Node_Expression_Constant('raw', $line),
       
    69             new Twig_Node(),
       
    70             $line
       
    71         );
       
    72     }
       
    73 
       
    74     protected function output(Twig_NodeInterface $node, $line = -1)
       
    75     {
       
    76         return new Twig_Node_Print($node, $line);
       
    77     }
       
    78 
       
    79     protected function getNodeValues(array $values)
       
    80     {
       
    81         $nodes = array();
       
    82         foreach ($values as $value) {
       
    83             if ($value instanceof Twig_NodeInterface) {
       
    84                 $nodes[] = $value;
       
    85             }
       
    86         }
       
    87 
       
    88         return $nodes;
       
    89     }
       
    90 
       
    91     static public function parseGrammar($str, $main = true)
       
    92     {
       
    93         static $cursor;
       
    94 
       
    95         if (true === $main) {
       
    96             $cursor = 0;
       
    97             $grammar = new Twig_Extensions_Grammar_Tag();
       
    98         } else {
       
    99             $grammar = new Twig_Extensions_Grammar_Optional();
       
   100         }
       
   101 
       
   102         while ($cursor < strlen($str)) {
       
   103             if (preg_match('/\s+/A', $str, $match, null, $cursor)) {
       
   104                 $cursor += strlen($match[0]);
       
   105             } elseif (preg_match('/<(\w+)(?:\:(\w+))?>/A', $str, $match, null, $cursor)) {
       
   106                 $class = sprintf('Twig_Extensions_Grammar_%s', ucfirst(isset($match[2]) ? $match[2] : 'Expression'));
       
   107                 if (!class_exists($class)) {
       
   108                     throw new Twig_Error_Runtime(sprintf('Unable to understand "%s" in grammar (%s class does not exist)', $match[0], $class));
       
   109                 }
       
   110                 $grammar->addGrammar(new $class($match[1]));
       
   111                 $cursor += strlen($match[0]);
       
   112             } elseif (preg_match('/\w+/A', $str, $match, null, $cursor)) {
       
   113                 $grammar->addGrammar(new Twig_Extensions_Grammar_Constant($match[0]));
       
   114                 $cursor += strlen($match[0]);
       
   115             } elseif (preg_match('/,/A', $str, $match, null, $cursor)) {
       
   116                 $grammar->addGrammar(new Twig_Extensions_Grammar_Constant($match[0], Twig_Token::PUNCTUATION_TYPE));
       
   117                 $cursor += strlen($match[0]);
       
   118             } elseif (preg_match('/\[/A', $str, $match, null, $cursor)) {
       
   119                 $cursor += strlen($match[0]);
       
   120                 $grammar->addGrammar(self::parseGrammar($str, false));
       
   121             } elseif (true !== $main && preg_match('/\]/A', $str, $match, null, $cursor)) {
       
   122                 $cursor += strlen($match[0]);
       
   123 
       
   124                 return $grammar;
       
   125             } else {
       
   126                 throw new Twig_Error_Runtime(sprintf('Unable to parse grammar "%s" near "...%s..."', $str, substr($str, $cursor, 10)));
       
   127             }
       
   128         }
       
   129 
       
   130         return $grammar;
       
   131     }
       
   132 }