TokenStream.php 3.9 KB

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