1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
//! <ost generic stream of symbols /// `IntStream::la` must return EOF in the end of stream pub const EOF: isize = -1; /// A simple stream of symbols whose values are represented as integers. This /// interface provides *marked ranges* with support for a minimum level /// of buffering necessary to implement arbitrary lookahead during prediction. pub trait IntStream { /// Consumes the current symbol in the stream. /// Advances this stream to the next element. /// /// This method has the following /// effects: /// /// - Forward movement: The value of `index` /// before calling this method is less than the value of `index` /// after calling this method. /// - Ordered lookahead: The value of {@code LA(1)} before /// calling this method becomes the value of {@code LA(-1)} after calling /// this method. /// /// Note that calling this method does not guarantee that `index()` is /// incremented by exactly 1. /// /// Allowed to panic if trying to consume EOF fn consume(&mut self); /// Lookaheads (or loopbacks if `i` is negative) /// /// Gets the value of the symbol at offset {@code i} from the current /// position. When {@code i==1}, this method returns the value of the current /// symbol in the stream (which is the next symbol to be consumed). When /// {@code i==-1}, this method returns the value of the previously read /// symbol in the stream. It is not valid to call this method with /// {@code i==0}, but the specific behavior is unspecified because this /// method is frequently called from performance-critical code. /// /// Note that default Lexer does not call this method with anything other than `-1` /// so it can be used for optimizations in downstream implementations. /// /// Must return `EOF` if `i` points to position at or beyond the end of the stream fn la(&mut self, i: isize) -> isize; /// After this call subsequent calls to seek must succeed if seek index is greater than mark index /// /// Returns marker that should be used later by `release` call to release this stream from fn mark(&mut self) -> isize; /// Releases `marker` fn release(&mut self, marker: isize); /// Returns current position of the input stream /// /// If there is active marker from `mark` then calling `seek` later with result of this call /// should put stream in same state it is currently in. fn index(&self) -> isize; /// Put stream back in state it was when it was in `index` position /// /// Allowed to panic if `index` does not belong to marked region(via `mark`-`release` calls) fn seek(&mut self, index: isize); /// Returns the total number of symbols in the stream. fn size(&self) -> isize; /// Returns name of the source this stream operates over if any fn get_source_name(&self) -> String; } /// Iterator over `IntStream` #[derive(Debug)] pub struct IterWrapper<'a, T: IntStream>(pub &'a mut T); impl<'a, T: IntStream> Iterator for IterWrapper<'a, T> { type Item = isize; fn next(&mut self) -> Option<Self::Item> { let result = self.0.la(1); self.0.consume(); match result { EOF => None, x => Some(x), } } }