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}