/* Copyright (c) 2012-2017 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. */ #pragma once #include "antlr4-common.h" namespace antlr4 { /// /// 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. /// For more information on marked ranges, see . ///

/// Initializing Methods: Some methods in this interface have /// unspecified behavior if no call to an initializing method has occurred after /// the stream was constructed. The following is a list of initializing methods: /// ///

///
class ANTLR4CPP_PUBLIC IntStream { public: static constexpr size_t EOF = std::numeric_limits::max(); /// The value returned by when the end of the stream is /// reached. /// No explicit EOF definition. We got EOF on all platforms. //static const size_t _EOF = std::ios::eofbit; /// /// The value returned by when the actual name of the /// underlying source is not known. /// static const std::string UNKNOWN_SOURCE_NAME; virtual ~IntStream(); /// /// Consumes the current symbol in the stream. This method has the following /// effects: /// ///
    ///
  • Forward movement: The value of /// before calling this method is less than the value of {@code 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 {@code index()} is /// incremented by exactly 1, as that would preclude the ability to implement /// filtering streams (e.g. which distinguishes /// between "on-channel" and "off-channel" tokens). ///
/// if an attempt is made to consume the the /// end of the stream (i.e. if {@code LA(1)==} before calling /// {@code consume}). virtual void consume() = 0; /// /// 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. ///

/// This method is guaranteed to succeed if any of the following are true: /// ///

    ///
  • {@code i>0}
  • ///
  • {@code i==-1} and returns a value greater /// than the value of {@code index()} after the stream was constructed /// and {@code LA(1)} was called in that order. Specifying the current /// {@code index()} relative to the index after the stream was created /// allows for filtering implementations that do not return every symbol /// from the underlying source. Specifying the call to {@code LA(1)} /// allows for lazily initialized streams.
  • ///
  • {@code LA(i)} refers to a symbol consumed within a marked region /// that has not yet been released.
  • ///
/// /// If {@code i} represents a position at or beyond the end of the stream, /// this method returns . ///

/// The return value is unspecified if {@code i<0} and fewer than {@code -i} /// calls to have occurred from the beginning of /// the stream before calling this method. ///

/// if the stream does not support /// retrieving the value of the specified symbol virtual size_t LA(ssize_t i) = 0; /// /// A mark provides a guarantee that operations will be /// valid over a "marked range" extending from the index where {@code mark()} /// was called to the current . This allows the use of /// streaming input sources by specifying the minimum buffering requirements /// to support arbitrary lookahead during prediction. ///

/// The returned mark is an opaque handle (type {@code int}) which is passed /// to when the guarantees provided by the marked /// range are no longer necessary. When calls to /// {@code mark()}/{@code release()} are nested, the marks must be released /// in reverse order of which they were obtained. Since marked regions are /// used during performance-critical sections of prediction, the specific /// behavior of invalid usage is unspecified (i.e. a mark is not released, or /// a mark is released twice, or marks are not released in reverse order from /// which they were created). ///

/// The behavior of this method is unspecified if no call to an /// has occurred after this stream was /// constructed. ///

/// This method does not change the current position in the input stream. ///

/// The following example shows the use of , /// , , and /// as part of an operation to safely work within a /// marked region, then restore the stream position to its original value and /// release the mark. ///

    /// IntStream stream = ...;
    /// int index = -1;
    /// int mark = stream.mark();
    /// try {
    ///   index = stream.index();
    ///   // perform work here...
    /// } finally {
    ///   if (index != -1) {
    ///     stream.seek(index);
    ///   }
    ///   stream.release(mark);
    /// }
    /// 
///
/// An opaque marker which should be passed to /// when the marked range is no longer required. virtual ssize_t mark() = 0; /// /// This method releases a marked range created by a call to /// . Calls to {@code release()} must appear in the /// reverse order of the corresponding calls to {@code mark()}. If a mark is /// released twice, or if marks are not released in reverse order of the /// corresponding calls to {@code mark()}, the behavior is unspecified. ///

/// For more information and an example, see . ///

/// A marker returned by a call to {@code mark()}. /// virtual void release(ssize_t marker) = 0; /// /// Return the index into the stream of the input symbol referred to by /// {@code LA(1)}. ///

/// The behavior of this method is unspecified if no call to an /// has occurred after this stream was /// constructed. ///

virtual size_t index() = 0; /// /// Set the input cursor to the position indicated by {@code index}. If the /// specified index lies past the end of the stream, the operation behaves as /// though {@code index} was the index of the EOF symbol. After this method /// returns without throwing an exception, the at least one of the following /// will be true. /// ///
    ///
  • will return the index of the first symbol /// appearing at or after the specified {@code index}. Specifically, /// implementations which filter their sources should automatically /// adjust {@code index} forward the minimum amount required for the /// operation to target a non-ignored symbol.
  • ///
  • {@code LA(1)} returns
  • ///
/// /// This operation is guaranteed to not throw an exception if {@code index} /// lies within a marked region. For more information on marked regions, see /// . The behavior of this method is unspecified if no call to /// an has occurred after this stream /// was constructed. ///
/// The absolute index to seek to. /// /// if {@code index} is less than 0 /// if the stream does not support /// seeking to the specified index virtual void seek(size_t index) = 0; /// /// Returns the total number of symbols in the stream, including a single EOF /// symbol. /// /// if the size of the stream is /// unknown. virtual size_t size() = 0; /// /// Gets the name of the underlying symbol source. This method returns a /// non-null, non-empty string. If such a name is not known, this method /// returns . /// virtual std::string getSourceName() const = 0; }; } // namespace antlr4