pigeon_core/
lib.rs

1//! # [`pigeon-core`]
2//! 
3//! ## Two-phase Parsing w/o Memorization
4//! In most PEG-based approaches, the target type is constructed during parsing. 
5//! However, some of them might be discarded in the near future, causing unwanted allocation/deallocation. 
6//! In this crate, we seperate parsing and type construction into two phases. 
7//! In the first phase, syntax items are represented as tags, which are storage-agnostic. 
8//! Then, an analysis pass run over the tags and generate a final result. 
9
10#![no_std]
11extern crate alloc;
12
13mod parser;
14mod prepend;
15mod ownptr;
16mod tuple;
17mod string;
18mod fromstr;
19
20// re-exports
21pub use crate::prepend::*;
22pub use crate::parser::*;
23pub use crate::fromstr::*;
24
25// re-exports
26use core::sync::atomic::AtomicUsize;
27pub use regex::Regex;
28pub use once_cell::unsync::Lazy as LazyCell;
29pub use once_cell::sync::Lazy as LazyLock;
30pub use alloc::vec::Vec;
31pub use stacker as stacker;
32
33#[derive(Debug)]
34pub struct Tag {
35    pub span: core::ops::Range<usize>,
36    pub rule: usize,
37}
38
39pub trait AstImpl<Extra: Copy> {
40    fn ast<'a>(
41        input: &'a str, 
42        stack: &'a [Tag], 
43        with: Extra
44    ) -> (&'a [Tag], Self);
45}
46
47pub trait ParseImpl<const GROUP: usize, const ERROR: bool> {
48    fn parse_impl(
49        input: &str, end: usize,
50        trace: &mut Vec<(usize, usize)>,
51        stack: &mut Vec<Tag>,
52    ) -> Result<usize, ()>;
53}
54
55pub trait RuleImpl<const RULE: usize, const ERROR: bool> {
56    fn rule_impl(
57        input: &str, end: usize, last: usize,
58        trace: &mut Vec<(usize, usize)>,
59        stack: &mut Vec<Tag>,
60    ) -> Result<usize, ()>;
61}
62
63pub static PIGEON_COUNT: AtomicUsize = AtomicUsize::new(0);
64
65pub trait Num {
66    fn num(rule: usize) -> usize;
67}
68
69pub trait Space {
70    fn space(input: &str, end: usize) -> Result<usize, ()> {
71        for (delta, ch) in input[end..].char_indices() {
72            if !ch.is_whitespace() { return Ok(end+delta) }
73        }
74        return Ok(input.len())
75    }
76}