antlr4rust 0.6.0

ANTLR4 runtime for Rust
Documentation
#![crate_type = "lib"]
// #![warn(rust_2018_idioms)]
// #![warn(missing_docs)] // warn if there is missing docs
// #![warn(missing_debug_implementations)]
// #![warn(trivial_numeric_casts)]

//! # Antlr4 runtime
//!
//! This is a Rust runtime for [ANTLR4] parser generator.
//! It is required to use parsers and lexers generated by [ANTLR4] parser generator
//!
//! This documentation refers to particular api used by generated parsers,lexers and syntax trees.
//!
//! For info on what is [ANTLR4] and how to generate parser please refer to:
//!  - [ANTLR4] main repository
//!  - [README] for Rust target
//!
//! [ANTLR4]: https://github.com/antlr/antlr4
//! [README]: https://github.com/rrevenantt/antlr4rust/blob/master/README.md
//!
//! ### Customization
//!
//! All input and output can be customized and optimized for particular usecase by implementing
//! related trait. Each of them already has different implementations that should be enough for most cases.
//! For more details see docs for corresponding trait and containing module.
//!
//! Currently available are:
//!  - [`CharStream`] - Lexer input, stream of char values with slicing support
//!  - [`TokenFactory`] - How lexer creates tokens.
//!  - [`Token`] - Element of [`TokenStream`]
//!  - [`TokenStream`] - Parser input, created from lexer or other token source.
//!  - [`ParserRuleContext`] - Node of created syntax tree.
//!
//! ### Zero-copy and lifetimes
//!
//! This library supports full zero-copy parsing. To allow this
//! `'input` lifetime is used everywhere inside to refer to data borrowed by parser/lexer.
//! Besides references to input it also can be [`TokenFactory`] if it returns references to tokens.
//! See [`ArenaFactory`] as an example of such behavior.
//! It allocates tokens in [`Arena`](typed_arena::Arena) and returns references.
//!
//! Using generated parse tree you should be careful to not require longer lifetime after the parsing.
//! If that's the case you will likely get "does not live long enough" error on the input string,
//! despite actual lifetime conflict is happening much later
//!
//! If you need to generate owned versions of parse tree or you want simpler usage,
//! you can opt out zero-copy by requiring `'input` to be static. In this case it is easier to also use
//! types that contains "owned" in their name or constructor function like `OwningTokenFactory`
//! or `InputStream::new_owned()`.
//!
//! ### Visitors and Listeners
//!
//! Parse listeners must outlive `'input` because they have to be stored inside of the parser.
//! It still allows to retrieve borrowed data from parse tree which should be enough to cover 99% use cases.
//!
//! `ParseTreeWalker` can accept listeners with arbitrary lifetime.
//!
//! `Visitor`s also can have arbitrary lifetime.
//!
//! ### Downcasting
//!
//! Rule context trait object support downcasting even for zero-copy case.
//! Also generic types(currently these are `H:ErrorStrategy` and `I:`[`TokenStream`]) that you can
//! access in generated parser from embedded actions also can be downcasted to concrete types.
//! To do it [`TidExt::downcast_*`](crate::tid::TidExt) extension methods should be used.
//! [`std::any::Any`] cannot be used here because parse tree nodes borrow from the input;
//! see the [`tid`](mod@crate::tid) module for the `Any` equivalent that works for a single
//! lifetime.
//!
//! [`CharStream`]: crate::char_stream::CharStream
//! [`TokenFactory`]: crate::token_factory::TokenFactory
//! [`ArenaFactory`]: crate::token_factory::ArenaFactory
//! [`Token`]: crate::token::Token
//! [`TokenStream`]: crate::token_stream::TokenStream
//! [`ParserRuleContext`]: crate::parser_rule_context::ParserRuleContext

#[macro_use]
extern crate lazy_static;

#[doc(hidden)]
pub use lazy_static::lazy_static;

#[doc(hidden)]
pub use parking_lot::RwLock;

#[doc(hidden)]
pub use tid::{type_id, Tid, TidAble, TidExt};

#[doc(inline)]
pub use error_strategy::{BailErrorStrategy, DefaultErrorStrategy, ErrorStrategy};

pub use input_stream::InputStream;

#[doc(inline)]
pub use lexer::{BaseLexer, Lexer};
#[doc(inline)]
pub use parser::{BaseParser, ListenerId, Parser};
#[doc(inline)]
pub use token_source::TokenSource;
//extern crate uuid;
#[doc(hidden)]
pub use prediction_context::PredictionContextCache;

#[doc(inline)]
pub use prediction_mode::PredictionMode;

#[doc(hidden)]
pub mod atn_config;
#[doc(hidden)]
pub mod atn_simulator;
pub mod int_stream;
mod lexer_action;
mod ll1_analyzer;
#[doc(hidden)]
pub mod recognizer;
pub mod token_factory;
//pub mod tokenstream_rewriter;
#[doc(hidden)]
pub mod atn_deserialization_options;
#[doc(hidden)]
pub mod atn_state;
pub mod char_stream;
#[doc(hidden)]
pub mod dfa_state;
#[doc(hidden)]
pub mod interval_set;
pub mod parser_rule_context;
mod prediction_context;
#[doc(hidden)]
pub mod semantic_context;
mod token_source;
pub mod token_stream;
//pub mod trace_listener;
#[doc(hidden)]
pub mod dfa;
#[doc(hidden)]
pub mod transition;
pub mod tree;
//pub mod file_stream;
#[doc(hidden)]
pub mod atn;
#[doc(hidden)]
pub mod atn_config_set;
#[doc(hidden)]
pub mod atn_deserializer;
pub mod common_token_stream;
mod dfa_serializer;
pub mod error_listener;
pub mod error_strategy;
pub mod errors;
pub mod input_stream;
pub mod lexer;
#[doc(hidden)]
pub mod lexer_action_executor;
pub mod lexer_atn_simulator;
pub mod parser;
pub mod parser_atn_simulator;
mod prediction_mode;
pub mod token;
pub mod trees;
mod utils;
//pub mod tokenstream_rewriter_test;
mod atn_type;
pub mod tid;
// mod context_factory;
pub mod rule_context;
pub mod vocabulary;
//#[cfg(test)]
// tests are either integration tests in "tests" foulder or unit tests in some modules

use std::rc::Rc;
/// Stable workaround for CoerceUnsized
///
/// # Safety
///
/// Implementors must ensure that each method, if it returns, returns its argument converted
/// to `Self` by a coercion, such as the unsized coercion from `T` to `dyn Trait` that the
/// `coerce_from!` macro performs with `from as _`. The result must refer to the same `T` value
/// in the same allocation, taking over the argument's ownership (`coerce_rc`, `coerce_box`) or
/// borrow (`coerce_ref`, `coerce_mut`). It must not drop, move, replace or reallocate that
/// value.
///
/// [`BaseParser::remove_parse_listener`](crate::parser::BaseParser::remove_parse_listener)
/// relies on this: it turns the box that `add_parse_listener` stored back into the caller's
/// `Box<L>`, which is only sound if that box still owns the caller's value.
///
/// Implement this trait through `coerce_from!`. A safe `impl` is rejected:
///
/// ```compile_fail,E0200
/// use antlr4rust::CoerceFrom;
/// use std::rc::Rc;
///
/// trait Listener {}
/// struct NotAListener;
///
/// impl CoerceFrom<NotAListener> for dyn Listener {
///     fn coerce_rc(_: Rc<NotAListener>) -> Rc<Self> { unimplemented!() }
///     fn coerce_box(_: Box<NotAListener>) -> Box<Self> { unimplemented!() }
///     fn coerce_ref(_: &NotAListener) -> &Self { unimplemented!() }
///     fn coerce_mut(_: &mut NotAListener) -> &mut Self { unimplemented!() }
/// }
/// ```
// #[doc(hidden)]
pub unsafe trait CoerceFrom<T> {
    fn coerce_rc(from: Rc<T>) -> Rc<Self>;
    fn coerce_box(from: Box<T>) -> Box<Self>;
    fn coerce_ref(from: &T) -> &Self;
    fn coerce_mut(from: &mut T) -> &mut Self;
}

#[doc(hidden)]
#[macro_export]
macro_rules! coerce_from {
    ($lt:lifetime : $p:path) => {
        const _: () = {
            use std::rc::Rc;
            // SAFETY: `CoerceFrom` requires each method to return its argument coerced to
            // `Self`, still referring to the same value in the same allocation. Every body
            // below is `from as _` with `T: $p + $lt` and `Self = dyn $p + $lt`, which is the
            // unsized coercion of `Rc<T>`, `Box<T>`, `&T` or `&mut T` to the same pointer type
            // over `Self`: the pointee is unsized in place, so the result points to the same
            // `T` with `T`'s vtable attached, and nothing is dropped, moved or reallocated.
            unsafe impl<$lt, T> $crate::CoerceFrom<T> for dyn $p + $lt
            where
                T: $p + $lt,
            {
                fn coerce_rc(from: Rc<T>) -> Rc<Self> {
                    from as _
                }
                fn coerce_box(from: Box<T>) -> Box<Self> {
                    from as _
                }
                fn coerce_ref(from: &T) -> &Self {
                    from as _
                }
                fn coerce_mut(from: &mut T) -> &mut Self {
                    from as _
                }
            }
        };
    };
}

/// Stable workaround for CoerceUnsized
///
/// # Safety
///
/// The same as for [`CoerceFrom`], with `self` as the argument: implementors must ensure that
/// each method, if it returns, returns `self` converted to `T` by a coercion, referring to the
/// same value in the same allocation and taking over its ownership or borrow.
/// [`BaseParser::add_parse_listener`](crate::parser::BaseParser::add_parse_listener) stores
/// what `coerce_box_to` returns, and `remove_parse_listener` relies on it being the caller's
/// box.
///
/// This trait is implemented for every `X` where `T: CoerceFrom<X>`; implement [`CoerceFrom`]
/// instead. A safe `impl` is rejected:
///
/// ```compile_fail,E0200
/// use antlr4rust::CoerceTo;
/// use std::rc::Rc;
///
/// trait Listener {}
/// struct NotAListener;
///
/// impl CoerceTo<dyn Listener> for NotAListener {
///     fn coerce_rc_to(self: Rc<Self>) -> Rc<dyn Listener> { unimplemented!() }
///     fn coerce_box_to(self: Box<Self>) -> Box<dyn Listener> { unimplemented!() }
///     fn coerce_ref_to(&self) -> &(dyn Listener + 'static) { unimplemented!() }
///     fn coerce_mut_to(&mut self) -> &mut (dyn Listener + 'static) { unimplemented!() }
/// }
/// ```
// #[doc(hidden)]
pub unsafe trait CoerceTo<T: ?Sized> {
    fn coerce_rc_to(self: Rc<Self>) -> Rc<T>;
    fn coerce_box_to(self: Box<Self>) -> Box<T>;
    fn coerce_ref_to(&self) -> &T;
    fn coerce_mut_to(&mut self) -> &mut T;
}

// SAFETY: `CoerceTo` requires each method to return `self` coerced to `T`, still referring to
// the same value in the same allocation. Each method passes `self` to the matching method of
// `T: CoerceFrom<X>` and returns its result unchanged, and the `CoerceFrom` contract guarantees
// exactly that of the result.
unsafe impl<T: ?Sized, X> CoerceTo<T> for X
where
    T: CoerceFrom<X>,
{
    fn coerce_rc_to(self: Rc<Self>) -> Rc<T> {
        T::coerce_rc(self)
    }
    fn coerce_box_to(self: Box<Self>) -> Box<T> {
        T::coerce_box(self)
    }

    fn coerce_ref_to(&self) -> &T {
        T::coerce_ref(self)
    }

    fn coerce_mut_to(&mut self) -> &mut T {
        T::coerce_mut(self)
    }
}

pub mod const_check {
    pub const fn version(maj: &str, min: &str) -> bool {
        if maj.is_empty() || min.is_empty() {
            return false;
        }
        byte_eq(VERSION_MAJ.as_bytes(), maj.as_bytes())
            && byte_eq(VERSION_MIN.as_bytes(), min.as_bytes())
    }

    const VERSION_MAJ: &str = env!("CARGO_PKG_VERSION_MAJOR");
    const VERSION_MIN: &str = env!("CARGO_PKG_VERSION_MINOR");

    const fn byte_eq(lhs: &[u8], rhs: &[u8]) -> bool {
        if lhs.len() != rhs.len() {
            return false;
        }
        let mut i: usize = 0;
        loop {
            if i >= lhs.len() {
                return true;
            }
            if lhs[i] != rhs[i] {
                return false;
            }
            i += 1;
        }
    }
}