Skip to main content

tygr/
grammar.rs

1//! Core [`Grammar`] trait and blanket implementations for standard Rust types.
2//!
3//! Every grammar type implements [`Grammar`], providing:
4//! - **parsing**  — `parse_at(input, pos, State) → Option<(Self, usize)>`
5//! - **printing** — `print_to(&self, buf)`
6//! - **BNF**      — `to_bnf() -> Expr`
7//!
8//! Parser uses ordered choice with backtracking. No left recursion.
9//!
10//! See the crate-level `## Design` section for how Rust constructs map to
11//! EBNF concepts.
12
13#[cfg(feature = "trace_one_node")]
14use crate::state::Context;
15#[cfg(feature = "trace_pos")]
16use crate::state::History;
17use crate::state::make_error;
18use crate::{Error, IntoInner, State, bnf::Expr};
19use either::Either::Left;
20use std::fmt;
21use std::marker::PhantomData;
22use std::ops::{Deref, DerefMut};
23use tygr_derive::Grammar;
24
25#[doc(hidden)]
26pub trait First {
27    type Concat<G: Grammar>: First;
28    type Union<X: First>: First;
29    type UnionByteSet<X: ByteSet>: First;
30    type UEmpty: First;
31    type UChar<const C: char>: First;
32    type UCharCI<const C: char>: First;
33    const CONTAINS_BYTE: [bool; 256];
34    const CONTAINS_NIL: bool;
35}
36
37#[doc(hidden)]
38pub trait ByteSet: First {}
39
40#[doc(hidden)]
41pub struct EmptyByteSet;
42impl ByteSet for EmptyByteSet {}
43impl First for EmptyByteSet {
44    type Concat<G: Grammar> = Self;
45
46    type Union<X: First> = X;
47
48    type UnionByteSet<X: ByteSet> = X;
49
50    type UEmpty = OptionalFirst<Self>;
51
52    type UChar<const D: char> = AddChar<Self, D>;
53
54    type UCharCI<const D: char> = AddCharCI<Self, D>;
55
56    const CONTAINS_BYTE: [bool; 256] = [false; 256];
57
58    const CONTAINS_NIL: bool = false;
59}
60
61#[doc(hidden)]
62pub struct AnyCharFirst;
63impl ByteSet for AnyCharFirst {}
64impl First for AnyCharFirst {
65    type Concat<G: Grammar> = Self;
66
67    type Union<X: First> = X::UnionByteSet<Self>;
68
69    type UnionByteSet<X: ByteSet> = Self;
70
71    type UEmpty = OptionalFirst<Self>;
72
73    type UChar<const D: char> = AddChar<Self, D>;
74
75    type UCharCI<const D: char> = AddCharCI<Self, D>;
76
77    const CONTAINS_BYTE: [bool; 256] = [true; 256];
78
79    const CONTAINS_NIL: bool = false;
80}
81
82#[doc(hidden)]
83pub struct AddChar<B: ByteSet, const C: char>(PhantomData<B>);
84impl<B: ByteSet, const C: char> ByteSet for AddChar<B, C> {}
85impl<B: ByteSet, const C: char> First for AddChar<B, C> {
86    type Concat<G: Grammar> = Self;
87
88    type Union<X: First> = X::UnionByteSet<Self>;
89
90    type UnionByteSet<X: ByteSet> = UnionSet<Self, X>;
91
92    type UEmpty = OptionalFirst<Self>;
93
94    type UChar<const D: char> = AddChar<Self, D>;
95
96    type UCharCI<const D: char> = AddCharCI<Self, D>;
97
98    const CONTAINS_BYTE: [bool; 256] = {
99        let mut map = B::CONTAINS_BYTE;
100        map[first_byte(C) as usize] = true;
101        map
102    };
103
104    const CONTAINS_NIL: bool = false;
105}
106
107/// First UTF-8 byte of `c` — the byte a first-set actually keys on.
108const fn first_byte(c: char) -> u8 {
109    let mut buf = [0u8; 4];
110    c.encode_utf8(&mut buf);
111    buf[0]
112}
113
114#[doc(hidden)]
115pub struct AddCharCI<B: ByteSet, const C: char>(PhantomData<B>);
116impl<B: ByteSet, const C: char> ByteSet for AddCharCI<B, C> {}
117impl<B: ByteSet, const C: char> First for AddCharCI<B, C> {
118    type Concat<G: Grammar> = Self;
119
120    type Union<X: First> = X::UnionByteSet<Self>;
121
122    type UnionByteSet<X: ByteSet> = UnionSet<Self, X>;
123
124    type UEmpty = OptionalFirst<Self>;
125
126    type UChar<const D: char> = AddChar<Self, D>;
127
128    type UCharCI<const D: char> = AddCharCI<Self, D>;
129
130    const CONTAINS_BYTE: [bool; 256] = {
131        let mut map = B::CONTAINS_BYTE;
132        map[first_byte(C.to_ascii_lowercase()) as usize] = true;
133        map[first_byte(C.to_ascii_uppercase()) as usize] = true;
134        map
135    };
136
137    const CONTAINS_NIL: bool = false;
138}
139
140/// Union of two byte sets — a single type node (O(1) depth per union) whose
141/// byte map is the elementwise OR of its operands.
142#[doc(hidden)]
143pub struct UnionSet<A: ByteSet, B: ByteSet>(PhantomData<(A, B)>);
144impl<A: ByteSet, B: ByteSet> ByteSet for UnionSet<A, B> {}
145impl<A: ByteSet, B: ByteSet> First for UnionSet<A, B> {
146    type Concat<G: Grammar> = Self;
147
148    type Union<X: First> = X::UnionByteSet<Self>;
149
150    type UnionByteSet<X: ByteSet> = UnionSet<Self, X>;
151
152    type UEmpty = OptionalFirst<Self>;
153
154    type UChar<const D: char> = AddChar<Self, D>;
155
156    type UCharCI<const D: char> = AddCharCI<Self, D>;
157
158    const CONTAINS_BYTE: [bool; 256] = {
159        let a = A::CONTAINS_BYTE;
160        let b = B::CONTAINS_BYTE;
161        let mut map = [false; 256];
162        let mut i = 0;
163        while i < 256 {
164            map[i] = a[i] || b[i];
165            i += 1;
166        }
167        map
168    };
169
170    const CONTAINS_NIL: bool = false;
171}
172
173pub(crate) type CharFirst<const C: char> = AddChar<EmptyByteSet, C>;
174pub(crate) type CharFirstCI<const C: char> = AddCharCI<EmptyByteSet, C>;
175
176#[doc(hidden)]
177pub struct OptionalFirst<B: ByteSet>(PhantomData<B>);
178
179impl<B: ByteSet> First for OptionalFirst<B> {
180    type Concat<G: Grammar> = <B as First>::Union<G::First>;
181
182    type Union<X: First> = <X::UnionByteSet<B> as First>::UEmpty;
183
184    type UnionByteSet<X: ByteSet> = <B::UnionByteSet<X> as First>::UEmpty;
185
186    type UEmpty = Self;
187
188    type UChar<const D: char> = <B::UChar<D> as First>::UEmpty;
189
190    type UCharCI<const D: char> = <B::UCharCI<D> as First>::UEmpty;
191
192    const CONTAINS_BYTE: [bool; 256] = B::CONTAINS_BYTE;
193
194    const CONTAINS_NIL: bool = true;
195}
196
197pub(crate) type EmptyFirst = OptionalFirst<EmptyByteSet>;
198
199/// Parse, print, and describe (as BNF) a grammar element.
200///
201/// Implement this by hand only for leaf/wrapper types; for `struct`s and
202/// `enum`s, `#[derive(Grammar)]` generates it (see the crate-level docs).
203pub trait Grammar: Sized + 'static {
204    /// The set of bytes (and whether empty input is valid) this grammar could start with.
205    type First: First;
206
207    /// Parse the entire `input` as `Self`, failing if any input is left unconsumed.
208    fn parse(input: &str) -> Result<Self, Error> {
209        #[cfg(feature = "trace_pos")]
210        let mut history = History::new();
211        #[cfg(feature = "trace_one_node")]
212        let context = Context::new();
213        let state = State::new(
214            #[cfg(feature = "trace_pos")]
215            &mut history,
216            #[cfg(feature = "trace_one_node")]
217            context,
218        );
219        if let Some((val, pos)) = Self::parse_at(input, 0, state)
220            && pos == input.len()
221        {
222            Ok(val)
223        } else {
224            Err(make_error(
225                #[cfg(feature = "trace_pos")]
226                history,
227            ))
228        }
229    }
230
231    /// Like [`parse`](Self::parse), but doesn't require consuming all of
232    /// `input` — returns the byte position just past the match, leaving any
233    /// remaining input unexamined.
234    fn parse_prefix(input: &str) -> Result<(Self, usize), Error> {
235        #[cfg(feature = "trace_pos")]
236        let mut history = History::new();
237        #[cfg(feature = "trace_one_node")]
238        let context = Context::new();
239        let state = State::new(
240            #[cfg(feature = "trace_pos")]
241            &mut history,
242            #[cfg(feature = "trace_one_node")]
243            context,
244        );
245        if let Some((val, pos)) = Self::parse_at(input, 0, state) {
246            Ok((val, pos))
247        } else {
248            Err(make_error(
249                #[cfg(feature = "trace_pos")]
250                history,
251            ))
252        }
253    }
254
255    /// Like [`parse`](Self::parse), but only checks that `input` is well-formed
256    /// and discards the parsed value.
257    fn scan(input: &str) -> Result<(), Error> {
258        #[cfg(feature = "trace_pos")]
259        let mut history = History::new();
260        #[cfg(feature = "trace_one_node")]
261        let context = Context::new();
262        let state = State::new(
263            #[cfg(feature = "trace_pos")]
264            &mut history,
265            #[cfg(feature = "trace_one_node")]
266            context,
267        );
268        if let Some(pos) = Self::scan_at(input, 0, state)
269            && pos == input.len()
270        {
271            Ok(())
272        } else {
273            Err(make_error(
274                #[cfg(feature = "trace_pos")]
275                history,
276            ))
277        }
278    }
279
280    /// Like [`scan`](Self::scan), but doesn't require consuming all of
281    /// `input` — returns the byte position just past the match, leaving any
282    /// remaining input unexamined.
283    fn scan_prefix(input: &str) -> Result<usize, Error> {
284        #[cfg(feature = "trace_pos")]
285        let mut history = History::new();
286        #[cfg(feature = "trace_one_node")]
287        let context = Context::new();
288        let state = State::new(
289            #[cfg(feature = "trace_pos")]
290            &mut history,
291            #[cfg(feature = "trace_one_node")]
292            context,
293        );
294        if let Some(pos) = Self::scan_at(input, 0, state) {
295            Ok(pos)
296        } else {
297            Err(make_error(
298                #[cfg(feature = "trace_pos")]
299                history,
300            ))
301        }
302    }
303
304    /// Attempt to parse `Self` starting at `pos`, returning the value and the
305    /// position just past it, or `None` on failure.
306    fn parse_at(input: &str, pos: usize, state: State) -> Option<(Self, usize)>;
307
308    /// Like [`parse_at`](Self::parse_at), but only checks well-formedness and
309    /// returns the end position.
310    fn scan_at(input: &str, pos: usize, state: State) -> Option<usize>;
311
312    /// Serialize `self` back to text, appending to `buf`.
313    fn print_to(&self, buf: &mut String);
314
315    /// Describe this grammar as a BNF/EBNF expression, for use in a
316    /// referencing rule's own definition.
317    fn to_bnf() -> Expr;
318
319    /// Record what this grammar would have expected at `pos`, without
320    /// attempting to actually parse — used when a caller already knows (e.g.
321    /// via `First`) that this alternative cannot match here, but still wants
322    /// it traced.
323    ///
324    /// Returns whether this grammar is *required* at `pos` (`Self::First`
325    /// doesn't contain nil). Sequential composition (`A::fail_at(..) ||
326    /// B::fail_at(..)`) can stop once a required element reports itself,
327    /// since real parsing would never reach anything after it either;
328    /// nullable elements return `false` so the chain keeps going.
329    fn fail_at(pos: usize, state: State) -> bool;
330
331    /// Serialize `self` to a new `String`; see [`print_to`](Self::print_to).
332    fn print(&self) -> String {
333        let mut buf = String::new();
334        self.print_to(&mut buf);
335        buf
336    }
337}
338
339/// A [`Grammar`] with a name and top-level BNF definition, so it can appear as
340/// its own rule (e.g. in [`bnf_rules!`](crate::bnf_rules)) rather than only
341/// inline in some other rule's definition.
342pub trait GrammarRule: Grammar {
343    /// The rule's name in BNF output; defaults to the type name.
344    const NAME: &'static str;
345
346    /// This rule's own definition, as opposed to [`to_bnf`](Grammar::to_bnf),
347    /// which is how *other* rules refer to it.
348    fn to_bnf_def() -> Expr;
349
350    /// Format this rule as a complete BNF line: `NAME = <definition> .`.
351    fn bnf_rule() -> String {
352        let mut s = String::new();
353        s.push_str(Self::NAME);
354        s.push_str(" = ");
355        let expr = Self::to_bnf_def();
356        expr.format(&mut s).unwrap();
357        s.push_str(" .");
358        s
359    }
360}
361
362/// Wrapper that hides a grammar element from BNF output.
363///
364/// Parses and prints just like the wrapped grammar, but is omitted from BNF.
365/// Useful for structural elements like whitespace.
366///
367/// ```
368/// # use tygr::*;
369/// # char_class!(IsSpace, "space", |ch| matches!(ch, ' ' | '\t'));
370/// type Ws = Hidden<StringOf<IsSpace>>;
371/// ```
372///
373/// Or use `#[grammar(hidden)]`:
374///
375/// ```
376/// # use tygr::*;
377/// # char_class!(IsSpace, "space", |ch| matches!(ch, ' ' | '\t'));
378/// #[derive(Grammar)]
379/// #[grammar(hidden)]
380/// struct Ws(StringOf<IsSpace>);
381/// ```
382#[derive(Debug, Clone, PartialEq, Eq, Hash, Grammar)]
383#[grammar(hidden)]
384pub struct Hidden<T>(T);
385
386impl<T> Deref for Hidden<T> {
387    type Target = T;
388    fn deref(&self) -> &T {
389        &self.0
390    }
391}
392
393impl<T> DerefMut for Hidden<T> {
394    fn deref_mut(&mut self) -> &mut T {
395        &mut self.0
396    }
397}
398
399impl<T> IntoInner<T> for Hidden<T> {
400    fn into_inner(self) -> T {
401        self.0
402    }
403}
404
405// ── Raw<T>  →  parse via T, store only the matched string ───────────────────
406
407/// Wrapper that parses using the wrapped grammar but keeps only the raw
408/// matched text as a `String`.
409///
410/// This is useful for grammar elements where the *structure* matters for
411/// parsing (e.g. `Ws` defined as `StringOf<IsSpace>`), but consumers
412/// only need the matched text.
413///
414/// ```
415/// # use tygr::*;
416/// # char_class!(IsDigit, "digit", |ch| ch.is_ascii_digit());
417/// # char_class!(IsSpace, "space", |ch| matches!(ch, ' ' | '\t'));
418/// #[derive(Grammar)]
419/// #[grammar(name = "ws", hidden)]
420/// struct Ws(StringOf<IsSpace>);
421///
422/// # #[derive(Grammar)]
423/// # struct Term(StringOf1<IsDigit>);
424/// # #[derive(Grammar)]
425/// # struct AddOp(StringEq!("+"));
426/// // Whitespace stored as string
427/// #[derive(Grammar)]
428/// #[grammar(name = "expr")]
429/// struct Expr(Term, Vec<(Raw<Ws>, AddOp, Raw<Ws>, Term)>);
430/// ```
431pub struct Raw<T>(pub String, PhantomData<T>);
432
433impl<T> Raw<T> {
434    /// Construct a `Raw` from an already-known string.
435    pub fn new(s: impl Into<String>) -> Self {
436        Raw(s.into(), PhantomData)
437    }
438
439    /// The matched text.
440    pub fn as_str(&self) -> &str {
441        &self.0
442    }
443}
444
445impl<T: Grammar> Grammar for Raw<T> {
446    type First = T::First;
447
448    #[inline]
449    fn parse_at(input: &str, pos: usize, state: State) -> Option<(Self, usize)> {
450        let new_pos = T::scan_at(input, pos, state)?;
451        Some((Raw(input[pos..new_pos].to_string(), PhantomData), new_pos))
452    }
453
454    #[inline]
455    fn scan_at(input: &str, pos: usize, state: State) -> Option<usize> {
456        let end = T::scan_at(input, pos, state)?;
457        Some(end)
458    }
459
460    fn print_to(&self, buf: &mut String) {
461        buf.push_str(&self.0);
462    }
463
464    fn to_bnf() -> Expr {
465        T::to_bnf()
466    }
467
468    fn fail_at(pos: usize, state: State) -> bool {
469        T::fail_at(pos, state)
470    }
471}
472
473// Manual trait impls — only the String matters, no bounds on T.
474
475impl<T> fmt::Debug for Raw<T> {
476    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
477        f.debug_tuple("Raw").field(&self.0).finish()
478    }
479}
480
481impl<T> Clone for Raw<T> {
482    fn clone(&self) -> Self {
483        Raw(self.0.clone(), PhantomData)
484    }
485}
486
487impl<T> PartialEq for Raw<T> {
488    fn eq(&self, other: &Self) -> bool {
489        self.0 == other.0
490    }
491}
492
493impl<T> Eq for Raw<T> {}
494
495impl<T> std::hash::Hash for Raw<T> {
496    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
497        self.0.hash(state);
498    }
499}
500
501impl<T> std::ops::Deref for Raw<T> {
502    type Target = str;
503    fn deref(&self) -> &str {
504        &self.0
505    }
506}
507
508impl<T> AsRef<str> for Raw<T> {
509    fn as_ref(&self) -> &str {
510        &self.0
511    }
512}
513
514impl<T> fmt::Display for Raw<T> {
515    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
516        f.write_str(&self.0)
517    }
518}
519
520impl<T> From<&str> for Raw<T> {
521    fn from(s: &str) -> Self {
522        Raw(s.to_string(), PhantomData)
523    }
524}
525
526impl<T> From<String> for Raw<T> {
527    fn from(s: String) -> Self {
528        Raw(s, PhantomData)
529    }
530}
531
532impl<T: Grammar> Grammar for Option<T> {
533    type First = <T::First as First>::UEmpty;
534
535    #[inline]
536    fn parse_at(input: &str, pos: usize, state: State) -> Option<(Self, usize)> {
537        match T::parse_at(input, pos, state) {
538            Some((val, new_pos)) => Some((Some(val), new_pos)),
539            None => Some((None, pos)),
540        }
541    }
542
543    #[inline]
544    fn scan_at(input: &str, pos: usize, state: State) -> Option<usize> {
545        match T::scan_at(input, pos, state) {
546            Some(end_pos) => Some(end_pos),
547            None => Some(pos),
548        }
549    }
550
551    fn print_to(&self, buf: &mut String) {
552        if let Some(val) = self {
553            val.print_to(buf);
554        }
555    }
556
557    fn to_bnf() -> Expr {
558        Expr::optional(T::to_bnf())
559    }
560
561    fn fail_at(pos: usize, state: State) -> bool {
562        T::fail_at(pos, state);
563        false
564    }
565}
566
567impl<T: Grammar> Grammar for Vec<T> {
568    type First = <T::First as First>::UEmpty;
569
570    #[inline]
571    fn parse_at(input: &str, mut pos: usize, mut state: State) -> Option<(Self, usize)> {
572        let mut items: Vec<T> = Vec::new();
573        while let Some((val, new_pos)) = { T::parse_at(input, pos, state.reborrow()) } {
574            if new_pos == pos {
575                break;
576            }
577            items.push(val);
578            pos = new_pos;
579        }
580        Some((items, pos))
581    }
582
583    #[inline]
584    fn scan_at(input: &str, mut pos: usize, mut state: State) -> Option<usize> {
585        while let Some(new_pos) = { T::scan_at(input, pos, state.reborrow()) } {
586            if new_pos == pos {
587                break;
588            }
589            pos = new_pos;
590        }
591        Some(pos)
592    }
593
594    fn print_to(&self, buf: &mut String) {
595        for item in self {
596            item.print_to(buf);
597        }
598    }
599
600    fn to_bnf() -> Expr {
601        Expr::repetition(T::to_bnf())
602    }
603
604    fn fail_at(pos: usize, state: State) -> bool {
605        T::fail_at(pos, state);
606        false
607    }
608}
609
610impl<T: Grammar> Grammar for Box<T> {
611    type First = T::First;
612
613    fn parse_at(input: &str, pos: usize, state: State) -> Option<(Self, usize)> {
614        let (val, new_pos) = T::parse_at(input, pos, state)?;
615        Some((Box::new(val), new_pos))
616    }
617
618    fn scan_at(input: &str, pos: usize, state: State) -> Option<usize> {
619        T::scan_at(input, pos, state)
620    }
621
622    fn print_to(&self, buf: &mut String) {
623        (**self).print_to(buf);
624    }
625
626    fn to_bnf() -> Expr {
627        T::to_bnf()
628    }
629
630    fn fail_at(pos: usize, state: State) -> bool {
631        T::fail_at(pos, state)
632    }
633}
634
635impl Grammar for () {
636    type First = EmptyFirst;
637
638    #[inline]
639    fn parse_at(_input: &str, pos: usize, _state: State) -> Option<(Self, usize)> {
640        Some(((), pos))
641    }
642
643    #[inline]
644    fn scan_at(_input: &str, pos: usize, _state: State) -> Option<usize> {
645        Some(pos)
646    }
647
648    fn print_to(&self, _buf: &mut String) {}
649
650    fn to_bnf() -> Expr {
651        Expr::empty()
652    }
653
654    fn fail_at(_pos: usize, _state: State) -> bool {
655        false
656    }
657}
658
659macro_rules! concat_first {
660    ($acc:ty;) => { $acc };
661    ($acc:ty; $T:ident $(, $rest:ident)*) => {
662        concat_first!(<$acc as First>::Concat<$T>; $($rest),*)
663    };
664}
665
666macro_rules! impl_grammar_tuple {
667    ($($idx:tt $T:ident),+) => {
668        impl<$($T: Grammar),+> Grammar for ($($T,)+) {
669            type First = concat_first!(EmptyFirst; $($T),+);
670
671            #[inline]
672            fn parse_at(
673                input: &str,
674                pos: usize,
675                #[allow(unused_mut)] mut state: State,
676            ) -> Option<(Self, usize)> {
677                let i = 0;
678                $(
679                    #[allow(non_snake_case)]
680                    let ($T, pos) = <$T>::parse_at(input, pos, state.reborrow())?;
681                    #[allow(unused_variables)]
682                    let i = i + 1;
683                )+
684                Some((($($T,)+), pos))
685            }
686
687            #[inline]
688            fn scan_at(
689                input: &str,
690                pos: usize,
691                #[allow(unused_mut)] mut state: State,
692            ) -> Option<usize> {
693                let i = 0;
694                $(
695                    #[allow(non_snake_case)]
696                    let pos =<$T>::scan_at(input, pos, state.reborrow())?;
697                    #[allow(unused_variables)]
698                    let i = i + 1;
699                )+
700                Some(pos)
701            }
702
703
704
705            fn print_to(&self, buf: &mut String) {
706                $(self.$idx.print_to(buf);)+
707            }
708
709            fn to_bnf() -> Expr {
710                Expr::sequence(vec![$(<$T>::to_bnf()),+])
711            }
712
713            fn fail_at(pos: usize, #[allow(unused_mut)] mut state: State) -> bool {
714                $( <$T>::fail_at(pos, state.reborrow()) || )+ false
715            }
716        }
717    };
718}
719
720impl_grammar_tuple!(0 A, 1 B);
721impl_grammar_tuple!(0 A, 1 B, 2 C);
722impl_grammar_tuple!(0 A, 1 B, 2 C, 3 D);
723impl_grammar_tuple!(0 A, 1 B, 2 C, 3 D, 4 E);
724impl_grammar_tuple!(0 A, 1 B, 2 C, 3 D, 4 E, 5 F);
725impl_grammar_tuple!(0 A, 1 B, 2 C, 3 D, 4 E, 5 F, 6 G);
726impl_grammar_tuple!(0 A, 1 B, 2 C, 3 D, 4 E, 5 F, 6 G, 7 H);
727impl_grammar_tuple!(0 A, 1 B, 2 C, 3 D, 4 E, 5 F, 6 G, 7 H, 8 I);
728impl_grammar_tuple!(0 A, 1 B, 2 C, 3 D, 4 E, 5 F, 6 G, 7 H, 8 I, 9 J);
729impl_grammar_tuple!(0 A, 1 B, 2 C, 3 D, 4 E, 5 F, 6 G, 7 H, 8 I, 9 J, 10 K);
730
731use either::Either::*;
732
733impl<A: Grammar, B: Grammar> Grammar for either::Either<A, B> {
734    type First = <A::First as First>::Union<B::First>;
735
736    #[inline]
737    fn parse_at(input: &str, pos: usize, mut state: State) -> Option<(Self, usize)> {
738        A::parse_at(input, pos, state.reborrow())
739            .map(|(x, end_pos)| (Left(x), end_pos))
740            .or_else(|| B::parse_at(input, pos, state).map(|(x, end_pos)| (Right(x), end_pos)))
741    }
742
743    #[inline]
744    fn scan_at(input: &str, pos: usize, mut state: State) -> Option<usize> {
745        A::scan_at(input, pos, state.reborrow()).or_else(|| B::scan_at(input, pos, state))
746    }
747
748    fn print_to(&self, buf: &mut String) {
749        match self {
750            Left(a) => a.print_to(buf),
751            Right(b) => b.print_to(buf),
752        }
753    }
754
755    fn to_bnf() -> Expr {
756        Expr::alternation(vec![A::to_bnf(), B::to_bnf()])
757    }
758
759    fn fail_at(pos: usize, mut state: State) -> bool {
760        let a = A::fail_at(pos, state.reborrow());
761        let b = B::fail_at(pos, state);
762        a && b
763    }
764}
765
766/// Zero-width negative lookahead: matches the empty string, but only when the
767/// following input does *not* match the wrapped grammar. Consumes nothing
768/// and prints nothing.
769///
770/// ```
771/// # use tygr::*;
772/// // "/" that is not the start of a "//" line comment.
773/// #[derive(Grammar)]
774/// struct Div(StringEq!("/"), NotFollowedBy<StringEq!("/")>);
775/// assert!(Div::parse("/").is_ok());
776/// assert!(Div::parse("//").is_err());
777/// ```
778pub struct NotFollowedBy<G>(PhantomData<G>);
779
780impl<G: Grammar> Grammar for NotFollowedBy<G> {
781    type First = EmptyFirst;
782
783    #[inline]
784    fn parse_at(input: &str, pos: usize, state: State) -> Option<(Self, usize)> {
785        let pos = Self::scan_at(input, pos, state)?;
786        Some((NotFollowedBy(PhantomData), pos))
787    }
788
789    #[inline]
790    fn scan_at(input: &str, pos: usize, mut state: State) -> Option<usize> {
791        // Silent lookahead: probe G on a throwaway history so a match (or miss)
792        // doesn't pollute the real error trace.
793        match state.probe(|state| G::scan_at(input, pos, state)) {
794            Some(_) => None,
795            None => Some(pos),
796        }
797    }
798
799    fn print_to(&self, _buf: &mut String) {}
800
801    fn to_bnf() -> Expr {
802        Expr::NotFollowedBy(Box::new(G::to_bnf()))
803    }
804
805    fn fail_at(_pos: usize, _state: State) -> bool {
806        false
807    }
808}
809
810// Hand-written rather than derived: `derive` would bound each impl on `G` (e.g.
811// `G: Clone`), but `G` is a phantom marker that's never stored, so these hold
812// unconditionally.
813impl<G> Default for NotFollowedBy<G> {
814    fn default() -> Self {
815        NotFollowedBy(PhantomData)
816    }
817}
818
819impl<G> fmt::Debug for NotFollowedBy<G> {
820    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
821        f.write_str("NotFollowedBy")
822    }
823}
824
825impl<G> Clone for NotFollowedBy<G> {
826    fn clone(&self) -> Self {
827        *self
828    }
829}
830
831impl<G> Copy for NotFollowedBy<G> {}
832
833impl<G> PartialEq for NotFollowedBy<G> {
834    fn eq(&self, _other: &Self) -> bool {
835        true
836    }
837}
838
839impl<G> Eq for NotFollowedBy<G> {}
840
841impl<G> std::hash::Hash for NotFollowedBy<G> {
842    fn hash<H: std::hash::Hasher>(&self, _state: &mut H) {}
843}
844
845/// Wrapper that records the `[start, end)` input span its ranged value was parsed from.
846#[derive(Debug, Clone, PartialEq, Eq)]
847pub struct Range<T> {
848    /// Byte offset where the ranged value started matching.
849    pub start: usize,
850    ranged: T,
851    /// Byte offset just past where the ranged value finished matching.
852    pub end: usize,
853}
854
855impl<T> IntoInner<T> for Range<T> {
856    fn into_inner(self) -> T {
857        self.ranged
858    }
859}
860
861impl<T> Deref for Range<T> {
862    type Target = T;
863    fn deref(&self) -> &Self::Target {
864        &self.ranged
865    }
866}
867
868impl<T> Range<T> {
869    /// Construct a `Range` from an already-known span.
870    pub fn new(start: usize, ranged: T, end: usize) -> Self {
871        Range { start, ranged, end }
872    }
873
874    /// Apply `f` to the ranged value, keeping the same span.
875    pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Range<U> {
876        Range {
877            start: self.start,
878            ranged: f(self.ranged),
879            end: self.end,
880        }
881    }
882
883    /// Borrow the ranged value, keeping the same span.
884    pub fn as_ref(&self) -> Range<&T> {
885        Range {
886            start: self.start,
887            ranged: &self.ranged,
888            end: self.end,
889        }
890    }
891}
892
893impl<T> Range<Option<T>> {
894    /// Swap `Range<Option<T>>` for `Option<Range<T>>`.
895    pub fn transpose(self) -> Option<Range<T>> {
896        match self.ranged {
897            Some(it) => Some(Range {
898                start: self.start,
899                ranged: it,
900                end: self.end,
901            }),
902            None => None,
903        }
904    }
905}
906
907impl<T, E> Range<Result<T, E>> {
908    /// Swap `Range<Result<T, E>>` for `Result<Range<T>, E>`.
909    pub fn transpose(self) -> Result<Range<T>, E> {
910        match self.ranged {
911            Ok(it) => Ok(Range {
912                start: self.start,
913                ranged: it,
914                end: self.end,
915            }),
916            Err(e) => Err(e),
917        }
918    }
919}
920
921impl<T: Grammar> Grammar for Range<T> {
922    type First = T::First;
923
924    #[inline]
925    fn parse_at(input: &str, pos: usize, state: State) -> Option<(Self, usize)> {
926        if let Some((it, new_pos)) = T::parse_at(input, pos, state) {
927            Some((
928                Range {
929                    start: pos,
930                    ranged: it,
931                    end: new_pos,
932                },
933                new_pos,
934            ))
935        } else {
936            None
937        }
938    }
939
940    #[inline]
941    fn scan_at(input: &str, pos: usize, state: State) -> Option<usize> {
942        T::scan_at(input, pos, state)
943    }
944
945    fn print_to(&self, buf: &mut String) {
946        self.ranged.print_to(buf);
947    }
948
949    fn to_bnf() -> Expr {
950        T::to_bnf()
951    }
952
953    fn fail_at(pos: usize, state: State) -> bool {
954        T::fail_at(pos, state)
955    }
956}
957
958/// Like `Vec`, but matches *one or more* items rather than zero or more.
959pub struct Vec1<T>(Vec<T>);
960
961impl<T> Deref for Vec1<T> {
962    type Target = Vec<T>;
963
964    fn deref(&self) -> &Self::Target {
965        &self.0
966    }
967}
968
969impl<T: Grammar> Grammar for Vec1<T> {
970    type First = T::First;
971
972    #[inline]
973    fn parse_at(input: &str, pos: usize, state: State) -> Option<(Self, usize)> {
974        let (x, pos) = <Vec<T>>::parse_at(input, pos, state).unwrap();
975        if x.is_empty() {
976            None
977        } else {
978            Some((Self(x), pos))
979        }
980    }
981
982    #[inline]
983    fn scan_at(input: &str, pos: usize, state: State) -> Option<usize> {
984        let end = <Vec<T>>::scan_at(input, pos, state).unwrap();
985        if end == pos { None } else { Some(end) }
986    }
987
988    fn print_to(&self, buf: &mut String) {
989        for t in self.iter() {
990            t.print_to(buf);
991        }
992    }
993
994    fn to_bnf() -> Expr {
995        Expr::sequence(vec![T::to_bnf(), <Vec<T>>::to_bnf()])
996    }
997
998    fn fail_at(pos: usize, mut state: State) -> bool {
999        T::fail_at(pos, state.reborrow()) || <Vec<T>>::fail_at(pos, state)
1000    }
1001}
1002
1003/// Consumes and discards input matching `T`, storing nothing. Prints nothing
1004/// back, since there's no value left to print.
1005impl<T: Grammar> Grammar for PhantomData<T> {
1006    type First = T::First;
1007
1008    #[inline]
1009    fn parse_at(input: &str, pos: usize, state: State) -> Option<(Self, usize)> {
1010        let pos = Self::scan_at(input, pos, state)?;
1011        Some((PhantomData, pos))
1012    }
1013
1014    #[inline]
1015    fn scan_at(input: &str, pos: usize, state: State) -> Option<usize> {
1016        T::scan_at(input, pos, state)
1017    }
1018
1019    fn print_to(&self, _buf: &mut String) {}
1020
1021    fn to_bnf() -> Expr {
1022        T::to_bnf()
1023    }
1024
1025    fn fail_at(pos: usize, state: State) -> bool {
1026        T::fail_at(pos, state)
1027    }
1028}
1029
1030/// Bridges a mapped type to its source grammar.
1031///
1032/// Every conversion derive (`GrammarFromStr`, `GrammarFromOther`,
1033/// `GrammarTryFromOther`) requires this: [`Source`](GrammarFrom::Source) is the
1034/// grammar to parse (BNF and `FIRST` fold into it), and
1035/// [`print_to`](GrammarFrom::print_to) serializes back, since the generated
1036/// `Grammar` impl builds `Self` from the source but can't print it.
1037/// Implementations typically reconstruct the source grammar and delegate, or
1038/// write the canonical text directly.
1039pub trait GrammarFrom {
1040    /// The grammar actually parsed; `Self` is built from it after the fact.
1041    type Source: Grammar;
1042
1043    /// Serialize `self` back to text (see [`Grammar::print_to`]).
1044    fn print_to(&self, buf: &mut String);
1045}