pub mod bnf;
mod char;
mod grammar;
mod olc;
mod state;
use std::ops::Deref;
pub use char::*;
pub use grammar::*;
pub use olc::*;
pub use state::*;
#[doc(hidden)]
pub use char::{CharCIThen, CharThen, StringEq, StringEqCI};
#[doc(hidden)]
extern crate self as tygr;
pub use tygr_derive::Grammar;
pub use tygr_derive::{GrammarFromOther, GrammarFromStr, GrammarTryFromOther};
pub use tygr_derive::StringEq;
pub use tygr_derive::StringEqCI;
#[macro_export]
macro_rules! bnf_rules {
($($T:ty),+ $(,)?) => {{
let mut _buf = ::std::string::String::new();
$(
if !_buf.is_empty() { _buf.push('\n'); }
_buf.push_str(&<$T as $crate::GrammarRule>::bnf_rule());
)+
_buf
}};
}
#[macro_export]
macro_rules! char_class {
($vis:vis $name:ident, $label:expr, |$ch:ident| $pred:expr) => {
$vis struct $name;
impl $crate::CharClass for $name {
fn matches($ch: char) -> bool { $pred }
fn name() -> &'static str { $label }
}
};
}
pub trait FilterResult {
fn be_valid(self) -> Option<&'static str>;
}
impl FilterResult for bool {
fn be_valid(self) -> Option<&'static str> {
if self { None } else { Some("be valid") }
}
}
impl FilterResult for Option<&'static str> {
fn be_valid(self) -> Option<&'static str> {
self
}
}
#[derive(Debug, Clone, PartialEq, Eq, Grammar)]
#[grammar(transparent)]
#[doc(hidden)]
pub struct SepItem<S, T> {
sep: S,
item: T,
}
#[derive(Debug, Clone, PartialEq, Eq, Grammar)]
#[grammar(transparent)]
pub struct VecSep<T, S> {
head: Box<T>,
rest: Vec<SepItem<S, T>>,
}
impl<T, S> VecSep<T, S> {
pub fn items(&self) -> impl Iterator<Item = &T> {
vec![self.head.as_ref()]
.into_iter()
.chain(self.rest.iter().map(|sep_item| &sep_item.item))
}
pub fn seps(&self) -> impl Iterator<Item = &S> {
self.rest.iter().map(|sep_item| &sep_item.sep)
}
pub fn into_item_sep(self) -> impl Iterator<Item = (T, S)> {
self.rest.into_iter().scan(*self.head, |prev, sep_item| {
let item = std::mem::replace(prev, sep_item.item);
Some((item, sep_item.sep))
})
}
pub fn first(&self) -> &T {
&self.head
}
pub fn last(&self) -> &T {
match self.rest.last() {
Some(sep_item) => &sep_item.item,
None => &self.head,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Grammar)]
#[grammar(transparent)]
pub struct Wrap<L, T, R> {
pub before: L,
pub wrapped: T,
pub after: R,
}
impl<L, T, R> Wrap<L, T, R> {
pub fn new(before: L, wrapped: T, after: R) -> Self {
Self {
before,
wrapped,
after,
}
}
pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Wrap<L, U, R> {
Wrap {
before: self.before,
wrapped: f(self.wrapped),
after: self.after,
}
}
}
impl<L, T, E, R> Wrap<L, Result<T, E>, R> {
pub fn transpose(self) -> Result<Wrap<L, T, R>, E> {
Ok(Wrap {
before: self.before,
wrapped: self.wrapped?,
after: self.after,
})
}
}
#[derive(Debug, Clone, PartialEq, Eq, Grammar)]
#[grammar(transparent)]
pub struct Prefix<P, T> {
prefix: P,
pub prefixed: T,
}
#[derive(Debug, Clone, PartialEq, Eq, Grammar)]
#[grammar(transparent)]
pub struct Suffix<T, S> {
suffixed: T,
suffix: S,
}
impl<L, T, R> Deref for Wrap<L, T, R> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.wrapped
}
}
impl<T, S> Deref for Suffix<T, S> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.suffixed
}
}
impl<P, T> Deref for Prefix<P, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.prefixed
}
}
impl<P, T> Prefix<P, T> {
pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Prefix<P, U> {
Prefix {
prefix: self.prefix,
prefixed: f(self.prefixed),
}
}
}
impl<P, T, E> Prefix<P, Result<T, E>> {
pub fn transpose(self) -> Result<Prefix<P, T>, E> {
Ok(Prefix {
prefix: self.prefix,
prefixed: self.prefixed?,
})
}
}
impl<T, S> Suffix<T, S> {
pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Suffix<U, S> {
Suffix {
suffixed: f(self.suffixed),
suffix: self.suffix,
}
}
}
impl<T, S, E> Suffix<Result<T, E>, S> {
pub fn transpose(self) -> Result<Suffix<T, S>, E> {
Ok(Suffix {
suffixed: self.suffixed?,
suffix: self.suffix,
})
}
}
pub trait IntoInner<T> {
fn into_inner(self) -> T;
}
impl<L, T, R> IntoInner<T> for Wrap<L, T, R> {
fn into_inner(self) -> T {
self.wrapped
}
}
impl<T, S> IntoInner<T> for Suffix<T, S> {
fn into_inner(self) -> T {
self.suffixed
}
}
impl<P, T> IntoInner<T> for Prefix<P, T> {
fn into_inner(self) -> T {
self.prefixed
}
}