1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
use std::borrow::Cow;
use crate::Span;
use super::{Literal, Rule};
#[derive(Clone)]
pub struct Alternation<'i> {
pub rules: Vec<Rule<'i>>,
pub(crate) span: Span,
}
impl<'i> Alternation<'i> {
pub(crate) fn new_expr(rules: Vec<Rule<'i>>) -> Rule<'i> {
rules
.into_iter()
.reduce(|a, b| match (a, b) {
(Rule::Alternation(mut a), Rule::Alternation(b)) => {
a.span = a.span.join(b.span);
a.rules.extend(b.rules);
Rule::Alternation(a)
}
(Rule::Alternation(mut a), b) => {
a.span = a.span.join(b.span());
a.rules.push(b);
Rule::Alternation(a)
}
(a, b) => {
let span = a.span().join(b.span());
Rule::Alternation(Alternation { rules: vec![a, b], span })
}
})
.unwrap_or_else(|| Rule::Literal(Literal::new(Cow::Borrowed(""), Span::default())))
}
#[cfg(feature = "dbg")]
pub(super) fn pretty_print(&self, buf: &mut crate::PrettyPrinter, needs_parens: bool) {
if needs_parens {
buf.start_indentation("(");
}
let len = self.rules.len();
for (i, rule) in self.rules.iter().enumerate() {
let needs_parens =
matches!(rule, Rule::Alternation(_) | Rule::Lookaround(_) | Rule::StmtExpr(_));
buf.push_str("| ");
buf.increase_indentation(2);
rule.pretty_print(buf, needs_parens);
buf.decrease_indentation(2);
if i < len - 1 {
buf.write("\n");
}
}
if needs_parens {
buf.end_indentation(")");
}
}
}