pomsky_syntax/exprs/
rule.rs

1use crate::Span;
2
3use super::{
4    Alternation, Boundary, CharClass, Group, Literal, Lookaround, Range, Recursion, Reference,
5    Regex, Repetition, StmtExpr, Variable, intersection::Intersection, negation::Negation,
6};
7
8/// A parsed pomsky expression, which might contain more sub-expressions.
9#[derive(Debug, Clone)]
10#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
11pub enum Rule {
12    /// A string literal
13    Literal(Literal),
14    /// A character class
15    CharClass(CharClass),
16    /// A group, i.e. a sequence of rules, possibly wrapped in parentheses.
17    Group(Group),
18    /// An alternation, i.e. a list of alternatives; at least one of them has to
19    /// match.
20    Alternation(Alternation),
21    /// An intersection, i.e. a list of rules that all have to match at the same time.
22    Intersection(Intersection),
23    /// A repetition, i.e. a expression that must be repeated. The number of
24    /// required repetitions is constrained by a lower and possibly an upper
25    /// bound.
26    Repetition(Box<Repetition>),
27    /// A boundary (start of string, end of string or word boundary).
28    Boundary(Boundary),
29    /// A (positive or negative) lookahead or lookbehind.
30    Lookaround(Box<Lookaround>),
31    /// An variable that has been declared before.
32    Variable(Variable),
33    /// A backreference or forward reference.
34    Reference(Reference),
35    /// A range of integers
36    Range(Range),
37    /// An expression preceded by a modifier such as `enable lazy;`
38    StmtExpr(Box<StmtExpr>),
39    /// Negated expression
40    Negation(Box<Negation>),
41    /// A regex string, which is not escaped
42    Regex(Regex),
43    /// A regex string, which is not escaped
44    Recursion(Recursion),
45
46    /// A Unicode grapheme
47    Grapheme,
48    /// A Unicode code point
49    Codepoint,
50    /// The dot
51    Dot,
52}
53
54impl Rule {
55    /// Returns the span of this rule
56    pub fn span(&self) -> Span {
57        match self {
58            Rule::Literal(l) => l.span,
59            Rule::CharClass(c) => c.span,
60            Rule::Group(g) => g.span,
61            Rule::Alternation(a) => a.span,
62            Rule::Intersection(i) => i.span,
63            Rule::Repetition(r) => r.span,
64            Rule::Boundary(b) => b.span,
65            Rule::Lookaround(l) => l.span,
66            Rule::Variable(v) => v.span,
67            Rule::Reference(r) => r.span,
68            Rule::Range(r) => r.span,
69            Rule::StmtExpr(m) => m.span,
70            Rule::Negation(n) => n.not_span.join(n.rule.span()),
71            Rule::Regex(r) => r.span,
72            Rule::Recursion(r) => r.span,
73            Rule::Grapheme | Rule::Codepoint | Rule::Dot => Span::empty(),
74        }
75    }
76
77    #[cfg(feature = "dbg")]
78    pub(crate) fn pretty_print(&self, buf: &mut crate::PrettyPrinter, needs_parens: bool) {
79        match self {
80            Rule::Literal(l) => l.pretty_print(buf),
81            Rule::CharClass(c) => c.pretty_print(buf),
82            Rule::Group(g) => g.pretty_print(buf, needs_parens),
83            Rule::Alternation(a) => a.pretty_print(buf, needs_parens),
84            Rule::Intersection(i) => i.pretty_print(buf, needs_parens),
85            Rule::Repetition(r) => r.pretty_print(buf),
86            Rule::Boundary(b) => b.pretty_print(buf),
87            Rule::Lookaround(l) => l.pretty_print(buf, needs_parens),
88            Rule::Variable(v) => v.pretty_print(buf),
89            Rule::Reference(r) => r.pretty_print(buf),
90            Rule::Range(r) => r.pretty_print(buf),
91            Rule::StmtExpr(s) => s.pretty_print(buf),
92            Rule::Negation(n) => n.pretty_print(buf, needs_parens),
93            Rule::Regex(r) => r.pretty_print(buf),
94            Rule::Recursion(_) => buf.push_str("recursion"),
95            Rule::Grapheme => buf.push_str("Grapheme"),
96            Rule::Codepoint => buf.push_str("Codepoint"),
97            Rule::Dot => buf.push_str("."),
98        }
99    }
100}
101
102#[cfg(feature = "dbg")]
103impl core::fmt::Display for Rule {
104    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
105        let mut buf = crate::PrettyPrinter::new();
106        self.pretty_print(&mut buf, false);
107        f.write_str(&buf.finish())
108    }
109}