1#![doc = include_str!("./README.md")]
2#![allow(clippy::type_complexity, clippy::new_ret_no_self)]
3
4use std::{
5 collections::VecDeque,
6 fmt::{self, Debug},
7 usize,
8};
9
10#[cfg(feature = "buffered")]
11pub use buffered_token_queue::*;
12#[cfg(feature = "generator")]
13pub use generator_token_queue::*;
14#[cfg(all(not(target_arch = "wasm32"), feature = "parallel"))]
15pub use parallel_token_queue::*;
16
17pub trait TokenTrait: PartialEq {
19 fn is_skippable(&self) -> bool {
21 false
22 }
23}
24
25#[cfg_attr(any(test, doctest), derive(PartialEq, Eq))]
27pub struct Token<T: TokenTrait, TData>(pub T, pub TData);
28
29impl<T: TokenTrait + Debug, TData: Debug> Debug for Token<T, TData> {
30 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31 f.debug_tuple("Token")
32 .field(&self.0)
33 .field(&self.1)
34 .finish()
35 }
36}
37
38pub trait TokenReader<T: TokenTrait, TData> {
40 fn peek(&mut self) -> Option<&Token<T, TData>>;
42
43 fn peek_n(&mut self, n: usize) -> Option<&Token<T, TData>>;
45
46 fn peek_mut(&mut self) -> Option<&mut Token<T, TData>>;
48
49 fn next(&mut self) -> Option<Token<T, TData>>;
51
52 fn conditional_next(&mut self, cb: impl FnOnce(&T) -> bool) -> Option<Token<T, TData>> {
54 let peek = self.peek()?;
55 if cb(&peek.0) {
56 self.next()
57 } else {
58 None
59 }
60 }
61
62 fn scan(&mut self, cb: impl FnMut(&T, &TData) -> bool) -> Option<&Token<T, TData>>;
68
69 fn expect_next(&mut self, expected_type: T) -> Result<TData, Option<(T, Token<T, TData>)>> {
75 match self.next() {
76 Some(token) => {
77 if token.0 == expected_type {
78 Ok(token.1)
79 } else if token.0.is_skippable() {
80 self.expect_next(expected_type)
82 } else {
83 Err(Some((expected_type, token)))
84 }
85 }
86 None => Err(None),
87 }
88 }
89}
90
91pub trait TokenSender<T: TokenTrait, TData> {
93 fn push(&mut self, token: Token<T, TData>) -> bool;
96}
97
98#[cfg(feature = "buffered")]
99mod buffered_token_queue {
100 use super::*;
101 pub struct BufferedTokenQueue<T: TokenTrait, TData> {
103 buffer: VecDeque<Token<T, TData>>,
104 }
105
106 impl<T: TokenTrait, TData> Default for BufferedTokenQueue<T, TData> {
107 fn default() -> Self {
108 Self {
109 buffer: Default::default(),
110 }
111 }
112 }
113
114 impl<T: TokenTrait, TData> BufferedTokenQueue<T, TData> {
115 pub fn new() -> Self {
117 Default::default()
118 }
119 }
120
121 impl<T: TokenTrait, TData> TokenSender<T, TData> for BufferedTokenQueue<T, TData> {
122 fn push(&mut self, token: Token<T, TData>) -> bool {
123 self.buffer.push_back(token);
124 true
125 }
126 }
127
128 impl<T: TokenTrait, TData> TokenReader<T, TData> for BufferedTokenQueue<T, TData> {
129 fn peek(&mut self) -> Option<&Token<T, TData>> {
130 self.buffer.front()
131 }
132
133 fn peek_n(&mut self, n: usize) -> Option<&Token<T, TData>> {
134 self.buffer.get(n)
135 }
136
137 fn peek_mut(&mut self) -> Option<&mut Token<T, TData>> {
138 self.buffer.front_mut()
139 }
140
141 fn next(&mut self) -> Option<Token<T, TData>> {
142 self.buffer.pop_front()
143 }
144
145 fn scan(&mut self, mut cb: impl FnMut(&T, &TData) -> bool) -> Option<&Token<T, TData>> {
146 let mut iter = self.buffer.iter().peekable();
147 while let Some(token) = iter.next() {
148 if cb(&token.0, &token.1) {
149 return iter.peek().copied();
150 }
151 }
152 None
153 }
154 }
155}
156
157#[cfg(all(not(target_arch = "wasm32"), feature = "parallel"))]
158mod parallel_token_queue {
159 use super::*;
160 use std::sync::mpsc::{sync_channel, Receiver, RecvError, SyncSender};
161
162 const DEFAULT_BUFFER_SIZE: usize = 20;
163
164 pub struct ParallelTokenQueue;
166
167 impl ParallelTokenQueue {
168 pub fn new<T: TokenTrait, TData>(
171 ) -> (ParallelTokenSender<T, TData>, ParallelTokenReader<T, TData>) {
172 Self::new_with_buffer_size(DEFAULT_BUFFER_SIZE)
173 }
174
175 pub fn new_with_buffer_size<T: TokenTrait, TData>(
176 buffer_size: usize,
177 ) -> (ParallelTokenSender<T, TData>, ParallelTokenReader<T, TData>) {
178 let (sender, receiver) = sync_channel::<Token<T, TData>>(buffer_size);
179
180 (
181 ParallelTokenSender(sender),
182 ParallelTokenReader {
183 receiver,
184 cache: VecDeque::new(),
185 },
186 )
187 }
188 }
189
190 #[doc(hidden)]
193 pub struct ParallelTokenSender<T: TokenTrait, TData>(SyncSender<Token<T, TData>>);
194
195 #[doc(hidden)]
196 pub struct ParallelTokenReader<T: TokenTrait, TData> {
197 receiver: Receiver<Token<T, TData>>,
198 cache: VecDeque<Token<T, TData>>,
199 }
200
201 impl<T: TokenTrait, TData> TokenSender<T, TData> for ParallelTokenSender<T, TData> {
202 fn push(&mut self, token: Token<T, TData>) -> bool {
203 self.0.send(token).is_ok()
204 }
205 }
206
207 impl<T: TokenTrait, TData> TokenReader<T, TData> for ParallelTokenReader<T, TData> {
208 fn peek(&mut self) -> Option<&Token<T, TData>> {
209 if self.cache.is_empty() {
210 match self.receiver.recv() {
211 Ok(token) => self.cache.push_back(token),
212 Err(RecvError) => {
214 return None;
215 }
216 }
217 }
218 self.cache.front()
219 }
220
221 fn peek_n(&mut self, n: usize) -> Option<&Token<T, TData>> {
222 while self.cache.len() <= n {
223 match self.receiver.recv() {
224 Ok(token) => self.cache.push_back(token),
225 Err(RecvError) => {
227 return None;
228 }
229 }
230 }
231 self.cache.get(n)
232 }
233
234 fn next(&mut self) -> Option<Token<T, TData>> {
235 if !self.cache.is_empty() {
236 return self.cache.pop_front();
237 }
238 self.receiver.recv().ok()
239 }
240
241 fn scan(&mut self, mut cb: impl FnMut(&T, &TData) -> bool) -> Option<&Token<T, TData>> {
242 let found = scan_cache(&mut self.cache, &mut cb);
243 let mut return_next = match found {
244 ScanCacheResult::RetrievableInCacheAt(idx) => return self.cache.get(idx),
245 ScanCacheResult::Found => true,
246 ScanCacheResult::NotFound => false,
247 };
248 loop {
249 match self.receiver.recv() {
250 Ok(val) => {
251 if return_next {
252 self.cache.push_back(val);
253 return self.cache.back();
254 }
255 if cb(&val.0, &val.1) {
256 return_next = true;
257 }
258 self.cache.push_back(val);
259 }
260 Err(RecvError) => {
262 return None;
263 }
264 }
265 }
266 }
267
268 fn peek_mut(&mut self) -> Option<&mut Token<T, TData>> {
269 if self.cache.is_empty() {
270 match self.receiver.recv() {
271 Ok(token) => self.cache.push_back(token),
272 Err(RecvError) => {
274 return None;
275 }
276 }
277 }
278 self.cache.front_mut()
279 }
280 }
281}
282
283#[cfg(feature = "generator")]
284mod generator_token_queue {
285 use super::*;
286
287 pub struct GeneratorTokenQueue<T, TData, TGeneratorState, TGenerator>
289 where
290 T: TokenTrait,
291 for<'a> TGenerator:
292 FnMut(&mut TGeneratorState, &mut GeneratorTokenQueueBuffer<'a, T, TData>),
293 {
294 generator: TGenerator,
295 generator_state: TGeneratorState,
296 cache: VecDeque<Token<T, TData>>,
297 }
298
299 pub struct GeneratorTokenQueueBuffer<'a, T: TokenTrait, TData>(
302 &'a mut VecDeque<Token<T, TData>>,
303 );
304
305 impl<'a, T: TokenTrait, TData> GeneratorTokenQueueBuffer<'a, T, TData> {
306 pub fn is_empty(&self) -> bool {
307 self.0.is_empty()
308 }
309
310 pub fn len(&self) -> usize {
311 self.0.len()
312 }
313 }
314
315 impl<'a, T: TokenTrait, TData> TokenSender<T, TData> for GeneratorTokenQueueBuffer<'a, T, TData> {
316 fn push(&mut self, token: Token<T, TData>) -> bool {
317 self.0.push_back(token);
318 true
319 }
320 }
321
322 impl<T, TData, TGeneratorState, TGenerator>
323 GeneratorTokenQueue<T, TData, TGeneratorState, TGenerator>
324 where
325 T: TokenTrait,
326 for<'a> TGenerator:
327 FnMut(&mut TGeneratorState, &mut GeneratorTokenQueueBuffer<'a, T, TData>),
328 {
329 pub fn new(generator: TGenerator, generator_state: TGeneratorState) -> Self {
331 GeneratorTokenQueue {
332 generator,
333 generator_state,
334 cache: VecDeque::new(),
335 }
336 }
337 }
338
339 impl<T, TData, TGeneratorState, TGenerator> TokenReader<T, TData>
340 for GeneratorTokenQueue<T, TData, TGeneratorState, TGenerator>
341 where
342 T: TokenTrait,
343 TData: Debug,
344 for<'a> TGenerator:
345 FnMut(&mut TGeneratorState, &mut GeneratorTokenQueueBuffer<'a, T, TData>),
346 {
347 fn peek(&mut self) -> Option<&Token<T, TData>> {
348 if self.cache.is_empty() {
349 (self.generator)(
350 &mut self.generator_state,
351 &mut GeneratorTokenQueueBuffer(&mut self.cache),
352 );
353 }
354 self.cache.front()
355 }
356
357 fn peek_n(&mut self, n: usize) -> Option<&Token<T, TData>> {
358 while self.cache.len() <= n {
359 (self.generator)(
360 &mut self.generator_state,
361 &mut GeneratorTokenQueueBuffer(&mut self.cache),
362 );
363 }
364 self.cache.get(n)
365 }
366
367 fn next(&mut self) -> Option<Token<T, TData>> {
368 if !self.cache.is_empty() {
369 return self.cache.pop_front();
370 }
371 (self.generator)(
372 &mut self.generator_state,
373 &mut GeneratorTokenQueueBuffer(&mut self.cache),
374 );
375 self.cache.pop_front()
376 }
377
378 fn scan(&mut self, mut cb: impl FnMut(&T, &TData) -> bool) -> Option<&Token<T, TData>> {
379 let cb = &mut cb;
380 let found = scan_cache(&mut self.cache, cb);
381 let mut return_next = match found {
382 ScanCacheResult::RetrievableInCacheAt(idx) => return self.cache.get(idx),
383 ScanCacheResult::Found => true,
384 ScanCacheResult::NotFound => false,
385 };
386 let mut found = None::<usize>;
387 while found.is_none() {
388 let start = self.cache.len();
389 (self.generator)(
390 &mut self.generator_state,
391 &mut GeneratorTokenQueueBuffer(&mut self.cache),
392 );
393 if self.cache.is_empty() {
394 return None;
395 }
396 for (idx, token) in self.cache.iter().enumerate().skip(start) {
397 if return_next {
398 found = Some(idx);
399 break;
400 }
401 if cb(&token.0, &token.1) {
402 return_next = true;
403 }
404 }
405 }
406 self.cache.get(found.unwrap())
407 }
408
409 fn peek_mut(&mut self) -> Option<&mut Token<T, TData>> {
410 if self.cache.is_empty() {
411 (self.generator)(
412 &mut self.generator_state,
413 &mut GeneratorTokenQueueBuffer(&mut self.cache),
414 );
415 }
416 self.cache.front_mut()
417 }
418 }
419}
420
421enum ScanCacheResult {
422 RetrievableInCacheAt(usize),
423 NotFound,
424 Found,
426}
427
428fn scan_cache<T: TokenTrait, TData>(
431 cache: &mut VecDeque<Token<T, TData>>,
432 cb: &mut impl FnMut(&T, &TData) -> bool,
433) -> ScanCacheResult {
434 let mut cb_returned_true_at_idx = None::<usize>;
435 for (idx, token) in cache.iter().enumerate() {
437 if cb(&token.0, &token.1) {
438 cb_returned_true_at_idx = Some(idx);
439 break;
440 }
441 }
442 if let Some(idx) = cb_returned_true_at_idx {
443 if idx + 1 < cache.len() {
444 ScanCacheResult::RetrievableInCacheAt(idx + 1)
445 } else {
446 ScanCacheResult::Found
447 }
448 } else {
449 ScanCacheResult::NotFound
450 }
451}
452
453#[cfg(feature = "sized-tokens")]
454pub mod sized_tokens {
455 use crate::{Token, TokenReader, TokenTrait};
456
457 pub trait SizedToken: TokenTrait {
459 fn length(&self) -> u32;
460 }
461
462 pub type TokenStart = source_map::Start;
463 pub type TokenEnd = source_map::End;
464
465 impl<T: SizedToken> Token<T, TokenStart> {
466 pub fn get_span(&self) -> source_map::Span {
467 let start = self.1 .0;
468 source_map::Span {
469 start,
470 end: self.1 .0 + self.0.length(),
471 source: (),
472 }
473 }
474
475 pub fn get_end(&self) -> TokenEnd {
476 source_map::End(self.1 .0 + self.0.length())
477 }
478 }
479
480 pub trait TokenReaderWithTokenEnds<T: SizedToken>: TokenReader<T, TokenStart> {
481 fn expect_next_get_end(
482 &mut self,
483 expected_type: T,
484 ) -> Result<TokenEnd, Option<(T, Token<T, TokenStart>)>> {
485 match self.next() {
486 Some(token) => {
487 if token.0 == expected_type {
488 Ok(token.get_end())
489 } else if token.0.is_skippable() {
490 self.expect_next_get_end(expected_type)
492 } else {
493 Err(Some((expected_type, token)))
494 }
495 }
496 None => Err(None),
497 }
498 }
499 }
500
501 impl<T, TR> TokenReaderWithTokenEnds<T> for TR
502 where
503 T: SizedToken,
504 TR: TokenReader<T, TokenStart>,
505 {
506 }
507}
508
509#[cfg(test)]
510mod tests {
511 use super::*;
512
513 impl TokenTrait for u32 {}
514
515 mod buffered_token_queue {
516 use super::{BufferedTokenQueue, Token, TokenReader, TokenSender};
517
518 #[test]
519 fn next() {
520 let mut btq = BufferedTokenQueue::new();
521 btq.push(Token(12, ()));
522 btq.push(Token(32, ()));
523 btq.push(Token(52, ()));
524
525 assert_eq!(btq.next().unwrap(), Token(12, ()));
526 assert_eq!(btq.next().unwrap(), Token(32, ()));
527 assert_eq!(btq.next().unwrap(), Token(52, ()));
528 assert!(btq.next().is_none());
529 }
530
531 #[test]
532 fn peek() {
533 let mut btq = BufferedTokenQueue::new();
534 btq.push(Token(12, ()));
535
536 assert_eq!(btq.peek().unwrap(), &Token(12, ()));
537 assert_eq!(btq.next().unwrap(), Token(12, ()));
538 assert!(btq.next().is_none());
539 }
540
541 #[test]
542 fn peek_n() {
543 let mut btq = BufferedTokenQueue::new();
544 btq.push(Token(12, ()));
545 btq.push(Token(32, ()));
546 btq.push(Token(52, ()));
547
548 assert_eq!(btq.peek_n(2).unwrap(), &Token(52, ()));
549 assert_eq!(btq.next().unwrap(), Token(12, ()));
550 assert_eq!(btq.next().unwrap(), Token(32, ()));
551 assert_eq!(btq.next().unwrap(), Token(52, ()));
552 assert!(btq.next().is_none());
553 }
554
555 #[test]
556 fn expect_next() {
557 let mut btq = BufferedTokenQueue::new();
558 btq.push(Token(12, ()));
559 btq.push(Token(24, ()));
560
561 assert_eq!(btq.expect_next(12).unwrap(), ());
562 assert!(btq.expect_next(10).is_err());
563 assert!(btq.next().is_none());
564 }
565
566 #[test]
567 fn scan() {
568 let mut btq = BufferedTokenQueue::new();
569 for val in vec![4, 10, 100, 200] {
570 btq.push(Token(val, ()));
571 }
572
573 let mut count = 0;
574 let x = btq.scan(move |token_val, _| {
575 count += token_val;
576 count > 100
577 });
578 assert_eq!(x.unwrap().0, 200);
579
580 let mut count = 0;
581 let y = btq.scan(move |token_val, _| {
582 count += token_val;
583 count > 1000
584 });
585 assert_eq!(y, None);
586
587 assert_eq!(btq.next().unwrap().0, 4);
588 assert_eq!(btq.next().unwrap().0, 10);
589 assert_eq!(btq.next().unwrap().0, 100);
590 assert_eq!(btq.next().unwrap().0, 200);
591 assert!(btq.next().is_none());
592 }
593 }
594
595 mod parallel_token_queue {
596 use super::{ParallelTokenQueue, Token, TokenReader, TokenSender};
597
598 #[test]
599 fn next() {
600 let (mut sender, mut reader) = ParallelTokenQueue::new();
601 std::thread::spawn(move || {
602 sender.push(Token(12, ()));
603 sender.push(Token(32, ()));
604 sender.push(Token(52, ()));
605 });
606
607 assert_eq!(reader.next().unwrap(), Token(12, ()));
608 assert_eq!(reader.next().unwrap(), Token(32, ()));
609 assert_eq!(reader.next().unwrap(), Token(52, ()));
610 assert!(reader.next().is_none());
611 }
612
613 #[test]
614 fn peek() {
615 let (mut sender, mut reader) = ParallelTokenQueue::new();
616 std::thread::spawn(move || {
617 sender.push(Token(12, ()));
618 });
619
620 assert_eq!(reader.peek().unwrap(), &Token(12, ()));
621 assert_eq!(reader.next().unwrap(), Token(12, ()));
622 assert!(reader.next().is_none());
623 }
624
625 #[test]
626 fn next_n() {
627 let (mut sender, mut reader) = ParallelTokenQueue::new();
628 std::thread::spawn(move || {
629 sender.push(Token(12, ()));
630 sender.push(Token(32, ()));
631 sender.push(Token(52, ()));
632 });
633
634 assert_eq!(reader.peek_n(2).unwrap(), &Token(52, ()));
635 assert_eq!(reader.next().unwrap(), Token(12, ()));
636 assert_eq!(reader.next().unwrap(), Token(32, ()));
637 assert_eq!(reader.next().unwrap(), Token(52, ()));
638 assert!(reader.next().is_none());
639 }
640
641 #[test]
642 fn expect_next() {
643 let (mut sender, mut reader) = ParallelTokenQueue::new();
644 std::thread::spawn(move || {
645 sender.push(Token(12, ()));
646 sender.push(Token(24, ()));
647 });
648
649 assert_eq!(reader.expect_next(12).unwrap(), ());
650 assert!(reader.expect_next(10).is_err());
651 assert!(reader.next().is_none());
652 }
653
654 #[test]
655 fn scan() {
656 let (mut sender, mut reader) = ParallelTokenQueue::new();
657 std::thread::spawn(move || {
658 for val in vec![4, 10, 100, 200] {
659 sender.push(Token(val, ()));
660 }
661 });
662
663 let mut count = 0;
664 let x = reader.scan(move |token_val, _| {
665 count += token_val;
666 count > 100
667 });
668 assert_eq!(x.unwrap().0, 200);
669
670 let mut count = 0;
671 let y = reader.scan(move |token_val, _| {
672 count += token_val;
673 count > 1000
674 });
675 assert_eq!(y, None);
676 assert_eq!(reader.next().unwrap().0, 4);
677 assert_eq!(reader.next().unwrap().0, 10);
678 assert_eq!(reader.next().unwrap().0, 100);
679 assert_eq!(reader.next().unwrap().0, 200);
680 assert!(reader.next().is_none());
681 }
682 }
683
684 mod generator_token_queue {
685 use super::{
686 GeneratorTokenQueue, GeneratorTokenQueueBuffer, Token, TokenReader, TokenSender,
687 };
688
689 fn lexer(state: &mut u32, sender: &mut GeneratorTokenQueueBuffer<u32, ()>) {
690 *state += 1;
691 match state {
692 1..=3 => {
693 sender.push(Token(*state * 2, ()));
694 }
695 _ => {}
696 }
697 }
698
699 #[test]
700 fn next() {
701 let mut reader = GeneratorTokenQueue::new(lexer, 0);
702
703 assert_eq!(reader.next().unwrap(), Token(2, ()));
704 assert_eq!(reader.next().unwrap(), Token(4, ()));
705 assert_eq!(reader.next().unwrap(), Token(6, ()));
706 assert!(reader.next().is_none());
707 }
708
709 #[test]
710 fn peek() {
711 let mut reader = GeneratorTokenQueue::new(lexer, 0);
712 assert_eq!(reader.peek().unwrap(), &Token(2, ()));
713 assert_eq!(reader.next().unwrap(), Token(2, ()));
714 }
715
716 #[test]
717 fn peek_n() {
718 let mut reader = GeneratorTokenQueue::new(lexer, 0);
719
720 assert_eq!(reader.peek_n(2).unwrap(), &Token(6, ()));
721 assert_eq!(reader.next().unwrap(), Token(2, ()));
722 assert_eq!(reader.next().unwrap(), Token(4, ()));
723 assert_eq!(reader.next().unwrap(), Token(6, ()));
724 assert!(reader.next().is_none());
725 }
726
727 #[test]
728 fn expect_next() {
729 let mut reader = GeneratorTokenQueue::new(lexer, 0);
730
731 assert!(reader.expect_next(2).is_ok());
732 assert!(reader.expect_next(5).is_err());
733 assert!(reader.expect_next(6).is_ok());
734 }
735
736 #[test]
737 fn scan() {
738 let mut reader = GeneratorTokenQueue::new(lexer, 0);
739
740 let mut count = 0;
741 let x = reader.scan(move |token_val, _| {
742 count += token_val;
743 count > 3
744 });
745 assert_eq!(x.unwrap().0, 6);
746 assert_eq!(reader.next().unwrap(), Token(2, ()));
747 }
748 }
749
750 #[test]
751 fn conditional_next() {
752 let mut btq = BufferedTokenQueue::new();
753 btq.push(Token(12, ()));
754 btq.push(Token(32, ()));
755
756 assert_eq!(btq.conditional_next(|t| *t == 28), None);
757 assert_eq!(btq.conditional_next(|t| *t == 12), Some(Token(12, ())));
758 assert_eq!(btq.next().unwrap(), Token(32, ()));
759 assert!(btq.next().is_none());
760 }
761
762 mod skippable_token {
763 use super::{BufferedTokenQueue, Token, TokenReader, TokenSender, TokenTrait};
764
765 #[derive(PartialEq, Eq, Debug)]
766 enum TokenType {
767 A,
768 B,
769 Ignore,
770 }
771
772 impl TokenTrait for TokenType {
773 fn is_skippable(&self) -> bool {
774 matches!(self, TokenType::Ignore)
775 }
776 }
777
778 #[test]
779 fn still_show_with_next() {
780 let mut btq = BufferedTokenQueue::new();
781 generate_tokens(&mut btq);
782
783 assert_eq!(btq.next().unwrap(), Token(TokenType::A, ()));
784 assert_eq!(btq.next().unwrap(), Token(TokenType::Ignore, ()));
785 assert_eq!(btq.next().unwrap(), Token(TokenType::B, ()));
786 assert!(btq.next().is_none());
787 }
788
789 #[test]
790 fn skipped_under_expect_next() {
791 let mut btq = BufferedTokenQueue::new();
792 generate_tokens(&mut btq);
793
794 assert!(btq.expect_next(TokenType::A).is_ok());
795 assert!(btq.expect_next(TokenType::B).is_ok());
796 assert!(btq.next().is_none());
797 }
798
799 fn generate_tokens(btq: &mut BufferedTokenQueue<TokenType, ()>) {
800 btq.push(Token(TokenType::A, ()));
801 btq.push(Token(TokenType::Ignore, ()));
802 btq.push(Token(TokenType::B, ()));
803 }
804 }
805}