#![no_std]
extern crate alloc;
mod parser;
mod prepend;
mod ownptr;
mod tuple;
mod fromstr;
mod span;
pub use crate::prepend::*;
pub use crate::parser::*;
pub use crate::fromstr::*;
pub use crate::span::*;
use core::fmt::Debug;
use core::sync::atomic::AtomicUsize;
pub use regex::Regex;
pub use once_cell::unsync::Lazy as LazyCell;
pub use once_cell::sync::Lazy as LazyLock;
pub use alloc::vec::Vec;
pub use stacker as stacker;
pub struct Tag {
pub span: core::ops::Range<usize>,
pub rule: usize,
}
impl Debug for Tag {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "[{} @ {:?}]", self.rule, self.span)
}
}
pub trait AstImpl<Extra: Copy> {
fn ast<'a>(
input: &'a str,
stack: &'a [Tag],
with: Extra
) -> (&'a [Tag], Self);
}
pub trait ParseImpl<const GROUP: usize, const ERROR: bool> {
fn parse_impl(
input: &str, end: usize, depth: usize, first: bool, trace: &mut Vec<usize>, stack: &mut Vec<Tag>, ) -> Result<usize, ()>;
}
pub trait RuleImpl<const RULE: usize, const ERROR: bool> {
fn rule_impl(
input: &str, end: usize, depth: usize, first: bool, trace: &mut Vec<usize>, stack: &mut Vec<Tag>, ) -> Result<usize, ()>;
}
pub static PEGGEN_COUNT: AtomicUsize = AtomicUsize::new(1);
pub trait Num {
fn num(rule: usize) -> usize;
}
pub trait Space {
#[inline(always)]
fn space(input: &str, end: usize) -> Result<usize, ()> {
for (delta, ch) in input[end..].char_indices() {
if !ch.is_whitespace() { return Ok(end+delta) }
}
return Ok(input.len())
}
}
#[inline(always)]
pub fn stack_sanity_check(input: &str, stack: &[Tag], span: core::ops::Range<usize>) {
#[cfg(debug_assertions)] {
let san = span.start == span.end || stack.last().map(|tag| (tag.span.start >= span.start && tag.span.end <= span.end) || tag.span.end <= span.start).unwrap_or(true);
if san { return }
use alloc::string::String;
let mut s = String::new();
for tag in stack.iter().rev() {
use core::fmt::Write;
writeln!(&mut s, "[RULE{}] {:?} @ {:?}", tag.rule, &input[tag.span.clone()], tag.span).unwrap();
}
panic!("internal error: incoming span starts earlier than current top, but it doesn't cover current top\nincoming span: {:?} @ {:?}\n{}", &input[span.clone()], span, s.trim());
}
}