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
use crate::*;
pub const NON: Re = Re::Set(Bset(0, 0));
pub const ALP: Re = Re::Set(Bset(!0, !0));
pub type Binop = fn(Pre, Pre) -> Re;
pub const ALT: Binop = Re::Alt;
pub const CAT: Binop = Re::Cat;
pub type Unop = fn(Pre) -> Re;
pub const NOT: Unop = Re::Not;
pub const KLE: Unop = Re::Kle;
pub const PLS: Unop = Re::Pls;
pub fn unop(f: Unop, x: Re) -> Re {
use Re::*;
match (f, x) {
(NOT, Kle(box ALP)) => NON,
(NOT, NON) => Kle(box ALP),
(NOT, Not(x)) => *x,
(f, x) => f(box x),
}
}
pub fn binop(f: Binop, l: Re, r: Re) -> Re {
use Re::*;
match (f, l, r) {
(ALT, _, x @ Kle(box ALP)) => x,
(ALT, x @ Kle(box ALP), _) => x,
(ALT, x, NON) => x,
(ALT, NON, x) => x,
(CAT, _, NON) => NON,
(CAT, NON, _) => NON,
(CAT, Cat(x, y), z) => binop(CAT, *x, binop(CAT, *y, z)),
(ALT, Alt(x, y), z) => binop(ALT, *x, binop(ALT, *y, z)),
(ALT, Set(x), Set(y)) => Set(x | y),
(ALT, x, y) if x == y => x,
(f, l, r) => f(box l, box r),
}
}