UNPKG

antlr4-runtime

Version:

JavaScript runtime for ANTLR4

99 lines (91 loc) 2.96 kB
/* Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. * Use of this file is governed by the BSD 3-clause license that * can be found in the LICENSE.txt file in the project root. */ import Token from './Token.js'; import BufferedTokenStream from './BufferedTokenStream.js'; /** * This class extends {@link BufferedTokenStream} with functionality to filter * token streams to tokens on a particular channel (tokens where * {@link Token//getChannel} returns a particular value). * * <p> * This token stream provides access to all tokens by index or when calling * methods like {@link //getText}. The channel filtering is only used for code * accessing tokens via the lookahead methods {@link //LA}, {@link //LT}, and * {@link //LB}.</p> * * <p> * By default, tokens are placed on the default channel * ({@link Token//DEFAULT_CHANNEL}), but may be reassigned by using the * {@code ->channel(HIDDEN)} lexer command, or by using an embedded action to * call {@link Lexer//setChannel}. * </p> * * <p> * Note: lexer rules which use the {@code ->skip} lexer command or call * {@link 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.</p> */ export default class CommonTokenStream extends BufferedTokenStream { constructor(lexer, channel) { super(lexer); this.channel = channel===undefined ? Token.DEFAULT_CHANNEL : channel; } adjustSeekIndex(i) { return this.nextTokenOnChannel(i, this.channel); } LB(k) { if (k===0 || this.index-k<0) { return null; } let i = this.index; let n = 1; // find k good tokens looking backwards while (n <= k) { // skip off-channel tokens i = this.previousTokenOnChannel(i - 1, this.channel); n += 1; } if (i < 0) { return null; } return this.tokens[i]; } LT(k) { this.lazyInit(); if (k === 0) { return null; } if (k < 0) { return this.LB(-k); } let i = this.index; let n = 1; // we know tokens[pos] is a good one // find k good tokens 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 += 1; } return this.tokens[i]; } // Count EOF just once. getNumberOfOnChannelTokens() { let n = 0; this.fill(); for (let i =0; i< this.tokens.length;i++) { const t = this.tokens[i]; if( t.channel===this.channel) { n += 1; } if( t.type===Token.EOF) { break; } } return n; } }