pomsky_syntax/exprs/
repetition.rs1use crate::{Span, error::RepetitionError};
2
3use super::Rule;
4
5#[derive(Debug, Clone)]
6#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
7pub struct Repetition {
8 pub rule: Rule,
9 pub kind: RepetitionKind,
10 pub quantifier: Quantifier,
11 pub span: Span,
12}
13
14impl Repetition {
15 pub(crate) fn new(
16 rule: Rule,
17 kind: RepetitionKind,
18 quantifier: Quantifier,
19 span: Span,
20 ) -> Self {
21 Repetition { rule, kind, quantifier, span }
22 }
23
24 #[cfg(feature = "dbg")]
25 pub(super) fn pretty_print(&self, buf: &mut crate::PrettyPrinter) {
26 self.rule.pretty_print(buf, true);
27 match self.kind {
28 RepetitionKind { lower_bound, upper_bound: None } => {
29 buf.push('{');
30 buf.write_fmt(lower_bound);
31 buf.push(',');
32 buf.push('}');
33 }
34 RepetitionKind { lower_bound, upper_bound: Some(upper_bound) }
35 if lower_bound == upper_bound =>
36 {
37 buf.push('{');
38 buf.write_fmt(lower_bound);
39 buf.push('}');
40 }
41 RepetitionKind { lower_bound, upper_bound: Some(upper_bound) } => {
42 buf.push('{');
43 buf.write_fmt(lower_bound);
44 buf.push(',');
45 buf.write_fmt(upper_bound);
46 buf.push('}');
47 }
48 }
49 match self.quantifier {
50 Quantifier::Greedy => buf.push_str(" greedy"),
51 Quantifier::Lazy => buf.push_str(" lazy"),
52 _ => {}
53 }
54 }
55}
56
57#[derive(Debug, Clone, PartialEq, Eq, Copy)]
58#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
59pub enum Quantifier {
60 Greedy,
61 Lazy,
62 DefaultGreedy,
63 DefaultLazy,
64}
65
66#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
74pub struct RepetitionKind {
75 pub lower_bound: u32,
77
78 pub upper_bound: Option<u32>,
80}
81
82#[cfg(feature = "arbitrary")]
83impl arbitrary::Arbitrary<'_> for RepetitionKind {
84 fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
85 let lower = u.int_in_range(0u8..=40)?;
86 if u.arbitrary()? {
87 let upper = u.int_in_range(lower..=lower + 40)?;
88 Ok(RepetitionKind { lower_bound: lower as u32, upper_bound: Some(upper as u32) })
89 } else {
90 Ok(RepetitionKind { lower_bound: lower as u32, upper_bound: None })
91 }
92 }
93}
94
95impl RepetitionKind {
96 pub(crate) fn zero_inf() -> Self {
97 RepetitionKind { lower_bound: 0, upper_bound: None }
98 }
99
100 pub(crate) fn one_inf() -> Self {
101 RepetitionKind { lower_bound: 1, upper_bound: None }
102 }
103
104 pub(crate) fn zero_one() -> Self {
105 RepetitionKind { lower_bound: 0, upper_bound: Some(1) }
106 }
107
108 pub(crate) fn fixed(n: u32) -> Self {
109 RepetitionKind { lower_bound: n, upper_bound: Some(n) }
110 }
111}
112
113impl TryFrom<(u32, Option<u32>)> for RepetitionKind {
114 type Error = RepetitionError;
115
116 fn try_from((lower_bound, upper_bound): (u32, Option<u32>)) -> Result<Self, Self::Error> {
117 if lower_bound > upper_bound.unwrap_or(u32::MAX) {
118 return Err(RepetitionError::NotAscending);
119 }
120
121 Ok(RepetitionKind { lower_bound, upper_bound })
122 }
123}