Skip to main content

rexact_core/
resolved.rs

1//! A resolved view of a pattern for backtracking analysis (milestone M8).
2//!
3//! Every leaf is already a [`CharSet`] under the dialect's rules (case folding,
4//! shorthand definitions, alphabet mode), so analyses need no dialect logic.
5//! Zero-width constructs are kept as terms of the shared [`TermStore`], which
6//! knows how to evaluate them against the input seen so far.
7
8use crate::charset::CharSet;
9use crate::term::TermId;
10
11/// A pattern node with leaves resolved to symbol sets.
12#[derive(Debug, Clone)]
13pub struct RNode {
14    /// Shape.
15    pub kind: RKind,
16    /// Byte-free source range (scalar offsets) in the original pattern text.
17    pub span: (usize, usize),
18}
19
20/// Node shapes.
21#[derive(Debug, Clone)]
22pub enum RKind {
23    /// Matches the empty string.
24    Empty,
25    /// One symbol from the set.
26    Set(CharSet),
27    /// Sequence.
28    Cat(Vec<RNode>),
29    /// Ordered alternation (backtracking engines try left to right).
30    Alt(Vec<RNode>),
31    /// Repetition; `max == None` is unbounded.
32    Repeat {
33        /// Body.
34        node: Box<RNode>,
35        /// Minimum count.
36        min: u64,
37        /// Maximum count.
38        max: Option<u64>,
39        /// Greedy (try more first) or lazy.
40        greedy: bool,
41    },
42    /// Zero-width assertion, evaluated by the term store at a position.
43    Assert(TermId),
44    /// `(?=x)` / `(?!x)`.
45    LookAhead {
46        /// Negative form.
47        neg: bool,
48        /// Body.
49        node: Box<RNode>,
50    },
51    /// `(?<=x)` / `(?<!x)`.
52    LookBehind {
53        /// Negative form.
54        neg: bool,
55        /// Body.
56        node: Box<RNode>,
57    },
58}