[ Index ] |
PHP Cross Reference of DokuWiki |
[Summary view] [Print] [Text view]
1 <?php 2 3 /* 4 * This file is part of the Symfony package. 5 * 6 * (c) Fabien Potencier <fabien@symfony.com> 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 namespace Symfony\Component\CssSelector\Parser; 13 14 use Symfony\Component\CssSelector\Exception\InternalErrorException; 15 use Symfony\Component\CssSelector\Exception\SyntaxErrorException; 16 17 /** 18 * CSS selector token stream. 19 * 20 * This component is a port of the Python cssselect library, 21 * which is copyright Ian Bicking, @see https://github.com/SimonSapin/cssselect. 22 * 23 * @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com> 24 * 25 * @internal 26 */ 27 class TokenStream 28 { 29 /** 30 * @var Token[] 31 */ 32 private $tokens = []; 33 34 /** 35 * @var Token[] 36 */ 37 private $used = []; 38 39 /** 40 * @var int 41 */ 42 private $cursor = 0; 43 44 /** 45 * @var Token|null 46 */ 47 private $peeked; 48 49 /** 50 * @var bool 51 */ 52 private $peeking = false; 53 54 /** 55 * Pushes a token. 56 * 57 * @return $this 58 */ 59 public function push(Token $token): self 60 { 61 $this->tokens[] = $token; 62 63 return $this; 64 } 65 66 /** 67 * Freezes stream. 68 * 69 * @return $this 70 */ 71 public function freeze(): self 72 { 73 return $this; 74 } 75 76 /** 77 * Returns next token. 78 * 79 * @throws InternalErrorException If there is no more token 80 */ 81 public function getNext(): Token 82 { 83 if ($this->peeking) { 84 $this->peeking = false; 85 $this->used[] = $this->peeked; 86 87 return $this->peeked; 88 } 89 90 if (!isset($this->tokens[$this->cursor])) { 91 throw new InternalErrorException('Unexpected token stream end.'); 92 } 93 94 return $this->tokens[$this->cursor++]; 95 } 96 97 /** 98 * Returns peeked token. 99 */ 100 public function getPeek(): Token 101 { 102 if (!$this->peeking) { 103 $this->peeked = $this->getNext(); 104 $this->peeking = true; 105 } 106 107 return $this->peeked; 108 } 109 110 /** 111 * Returns used tokens. 112 * 113 * @return Token[] 114 */ 115 public function getUsed(): array 116 { 117 return $this->used; 118 } 119 120 /** 121 * Returns nex identifier token. 122 * 123 * @return string The identifier token value 124 * 125 * @throws SyntaxErrorException If next token is not an identifier 126 */ 127 public function getNextIdentifier(): string 128 { 129 $next = $this->getNext(); 130 131 if (!$next->isIdentifier()) { 132 throw SyntaxErrorException::unexpectedToken('identifier', $next); 133 } 134 135 return $next->getValue(); 136 } 137 138 /** 139 * Returns nex identifier or star delimiter token. 140 * 141 * @return string|null The identifier token value or null if star found 142 * 143 * @throws SyntaxErrorException If next token is not an identifier or a star delimiter 144 */ 145 public function getNextIdentifierOrStar(): ?string 146 { 147 $next = $this->getNext(); 148 149 if ($next->isIdentifier()) { 150 return $next->getValue(); 151 } 152 153 if ($next->isDelimiter(['*'])) { 154 return null; 155 } 156 157 throw SyntaxErrorException::unexpectedToken('identifier or "*"', $next); 158 } 159 160 /** 161 * Skips next whitespace if any. 162 */ 163 public function skipWhitespace() 164 { 165 $peek = $this->getPeek(); 166 167 if ($peek->isWhitespace()) { 168 $this->getNext(); 169 } 170 } 171 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body