TokenStream.php (4108B)
1 <?php 2 3 /* 4 * This file is part of Twig. 5 * 6 * (c) 2009 Fabien Potencier 7 * (c) 2009 Armin Ronacher 8 * 9 * For the full copyright and license information, please view the LICENSE 10 * file that was distributed with this source code. 11 */ 12 13 /** 14 * Represents a token stream. 15 * 16 * @author Fabien Potencier <fabien@symfony.com> 17 */ 18 class Twig_TokenStream 19 { 20 protected $tokens; 21 protected $current = 0; 22 protected $filename; 23 24 /** 25 * Constructor. 26 * 27 * @param array $tokens An array of tokens 28 * @param string $filename The name of the filename which tokens are associated with 29 */ 30 public function __construct(array $tokens, $filename = null) 31 { 32 $this->tokens = $tokens; 33 $this->filename = $filename; 34 } 35 36 /** 37 * Returns a string representation of the token stream. 38 * 39 * @return string 40 */ 41 public function __toString() 42 { 43 return implode("\n", $this->tokens); 44 } 45 46 public function injectTokens(array $tokens) 47 { 48 $this->tokens = array_merge(array_slice($this->tokens, 0, $this->current), $tokens, array_slice($this->tokens, $this->current)); 49 } 50 51 /** 52 * Sets the pointer to the next token and returns the old one. 53 * 54 * @return Twig_Token 55 */ 56 public function next() 57 { 58 if (!isset($this->tokens[++$this->current])) { 59 throw new Twig_Error_Syntax('Unexpected end of template.', $this->tokens[$this->current - 1]->getLine(), $this->filename); 60 } 61 62 return $this->tokens[$this->current - 1]; 63 } 64 65 /** 66 * Tests a token, sets the pointer to the next one and returns it or throws a syntax error. 67 * 68 * @return Twig_Token|null The next token if the condition is true, null otherwise 69 */ 70 public function nextIf($primary, $secondary = null) 71 { 72 if ($this->tokens[$this->current]->test($primary, $secondary)) { 73 return $this->next(); 74 } 75 } 76 77 /** 78 * Tests a token and returns it or throws a syntax error. 79 * 80 * @return Twig_Token 81 */ 82 public function expect($type, $value = null, $message = null) 83 { 84 $token = $this->tokens[$this->current]; 85 if (!$token->test($type, $value)) { 86 $line = $token->getLine(); 87 throw new Twig_Error_Syntax(sprintf('%sUnexpected token "%s" of value "%s" ("%s" expected%s).', 88 $message ? $message.'. ' : '', 89 Twig_Token::typeToEnglish($token->getType()), $token->getValue(), 90 Twig_Token::typeToEnglish($type), $value ? sprintf(' with value "%s"', $value) : ''), 91 $line, 92 $this->filename 93 ); 94 } 95 $this->next(); 96 97 return $token; 98 } 99 100 /** 101 * Looks at the next token. 102 * 103 * @param int $number 104 * 105 * @return Twig_Token 106 */ 107 public function look($number = 1) 108 { 109 if (!isset($this->tokens[$this->current + $number])) { 110 throw new Twig_Error_Syntax('Unexpected end of template.', $this->tokens[$this->current + $number - 1]->getLine(), $this->filename); 111 } 112 113 return $this->tokens[$this->current + $number]; 114 } 115 116 /** 117 * Tests the current token. 118 * 119 * @return bool 120 */ 121 public function test($primary, $secondary = null) 122 { 123 return $this->tokens[$this->current]->test($primary, $secondary); 124 } 125 126 /** 127 * Checks if end of stream was reached. 128 * 129 * @return bool 130 */ 131 public function isEOF() 132 { 133 return $this->tokens[$this->current]->getType() === Twig_Token::EOF_TYPE; 134 } 135 136 /** 137 * Gets the current token. 138 * 139 * @return Twig_Token 140 */ 141 public function getCurrent() 142 { 143 return $this->tokens[$this->current]; 144 } 145 146 /** 147 * Gets the filename associated with this stream. 148 * 149 * @return string 150 */ 151 public function getFilename() 152 { 153 return $this->filename; 154 } 155 }