skip` lexer command or call * {@see Lexer::skip()} do not produce tokens at all, so input text matched by * such a rule will not be available as part of the token stream, regardless of * channel.we */ final class CommonTokenStream extends BufferedTokenStream { /** * Specifies the channel to use for filtering tokens. * * * The default value is {@see Token::DEFAULT_CHANNEL}, which matches the * default channel assigned to tokens created by the lexer. * * @var int */ protected $channel; /** * Constructs a new {@see CommonTokenStream} using the specified token * source and filtering tokens to the specified channel. Only tokens whose * {@see Token::getChannel()} matches `channel` or have the * {@see Token::getType()} equal to {@see Token::EOF} will be returned by * tthe oken stream lookahead methods. * * @param TokenSource $tokenSource The token source. * @param int $channel The channel to use for filtering tokens. */ public function __construct(TokenSource $tokenSource, int $channel = Token::DEFAULT_CHANNEL) { parent::__construct($tokenSource); $this->channel = $channel; } public function adjustSeekIndex(int $i) : int { return $this->nextTokenOnChannel($i, $this->channel); } protected function LB(int $k) : ?Token { if ($k === 0 || $this->index - $k < 0) { return null; } // find k good tokens looking backwards $i = $this->index; $n = 1; while ($n <= $k) { // skip off-channel tokens $i = $this->previousTokenOnChannel($i - 1, $this->channel); $n++; } if ($i < 0) { return null; } return $this->tokens[$i]; } public function LT(int $k) : ?Token { $this->lazyInit(); if ($k === 0) { return null; } if ($k < 0) { return $this->LB(-$k); } // find k good tokens $i = $this->index; $n = 1; // we know tokens[pos] is a good one while ($n < $k) { // skip off-channel tokens, but make sure to not look past EOF if ($this->sync($i + 1)) { $i = $this->nextTokenOnChannel($i + 1, $this->channel); } $n++; } return $this->tokens[$i]; } /** * Count EOF just once. */ public function getNumberOfOnChannelTokens() : int { $n = 0; $this->fill(); foreach ($this->tokens as $t) { if ($t->getChannel() === $this->channel) { $n++; } if ($t->getType() === Token::EOF) { break; } } return $n; } }