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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
//! [`Combinator`] is a wrapper around an [`Action`] to provide decorators and operator overloads.
//! # Provided Combinators
//! To get started, you can use the provided combinators like [`eat`],
//! which will eat the provided pattern from the rest of the input text:
//! ```
//! # use whitehole::{combinator::{eat, Combinator}, action::Action};
//! # fn t(_: Combinator<impl Action<Text = str>>) {}
//! # t(
//! eat("true")
//! # );
//! ```
//! To save the memory of your brain, we have very limited number of provided combinators.
//! Here are them all:
//! - [`eat`]: eat a pattern.
//! - [`till`]: eat until a pattern, inclusive.
//! - [`next`]: eat the next char or byte by a predicate.
//! - [`take`]: take the next `n` chars or bytes.
//! - [`wrap`]: wrap a closure as a combinator.
//! - [`recur`]: create a recursive combinator.
//!
//! Tips: Some of the provided combinators may have faster `unsafe` variants
//! named with suffix `_unchecked`.
//!
//! To parse bytes, see the [`bytes`] module for the provided combinators with the same name.
//! # Composition
//! Use `+` and `|` to compose multiple combinators
//! for more complex tasks:
//! ```
//! # use whitehole::{combinator::{eat, Combinator}, action::Action};
//! # fn t(_: Combinator<impl Action<Text = str>>) {}
//! // match "true" then match "false"
//! # t(
//! eat("true") + eat("false")
//! # );
//! // match "true" or "false"
//! # t(
//! eat("true") | eat("false")
//! # );
//! ```
//! See [`ops::add`] and [`ops::bitor`] for more information.
//! # Repetition
//! Use `*` to repeat a combinator:
//! ```
//! # use whitehole::{combinator::{eat, Combinator}, action::Action};
//! # fn t(_: Combinator<impl Action<Text = str>>) {}
//! // repeat the combinator for 2 times
//! # t(
//! eat("true") * 2
//! # );
//! // similar to
//! # t(
//! eat("true") + "true"
//! # );
//!
//! // repeat the combinator with a range, greedy
//! # t(
//! eat("true") * (1..=3)
//! # );
//! // similar to but faster than
//! # t(
//! (eat("true") + "true" + "true") | (eat("true") + "true") | eat("true")
//! # );
//! ```
//! See [`ops::mul`] for more information.
//! # Lookahead
//! Use `!` for negative lookahead:
//! ```
//! # use whitehole::{combinator::{eat, Combinator}, action::Action};
//! # fn t(_: Combinator<impl Action<Text = str>>) {}
//! // reject if the next char is 'a', otherwise accept with 0 digested
//! // (negative lookahead)
//! # t(
//! !eat('a')
//! # );
//! // apply twice to realize positive lookahead
//! # t(
//! !!eat('a')
//! # );
//! ```
//! See [`ops::not`] for more information.
//! # Decorator
//! [`Combinator`] provides a set of methods as decorators
//! to modify the behavior of the combinator.
//! ## Debug
//! - [`Combinator::log`] to print debug information.
//! ## Flow Control
//! - [`Combinator::optional`] to make a combinator optional.
//! - [`Combinator::when`] to conditionally execute the combinator.
//! - [`Combinator::prevent`] to conditionally reject the combinator before it is executed.
//! - [`Combinator::reject`] to conditionally reject the combinator after it is executed.
//! - [`Combinator::boundary`] to require a word boundary after the action is accepted.
//! ## Value Transformation
//! You can set [`Output::value`] to distinguish different output types
//! or carrying additional data.
//!
//! Related decorators:
//! - [`Combinator::map`] to convert the value to a new value.
//! - [`Combinator::bind`] to set the value to a provided clone-able value.
//! - [`Combinator::bind_with`] to set the value with a provided factory.
//! - [`Combinator::select`] to calculate the value with a closure.
//! - [`Combinator::tuple`] to wrap the value in an one-element tuple.
//! - [`Combinator::pop`] to unwrap the value from the one-element tuple.
//! - [`Combinator::range`] to wrap the value in a [`WithRange`](crate::range::WithRange) struct.
//! ## State Manipulation
//! [`Combinator`]s are stateless, but you can access external states
//! via [`Input::state`] to realize stateful parsing.
//!
//! Related decorators:
//! - [`Combinator::prepare`] to modify states before being executed.
//! - [`Combinator::then`] to modify states after being accepted.
//! - [`Combinator::catch`] to modify states after being rejected.
//! - [`Combinator::finally`] to modify states after being executed.
//! # Contextual
//! By default and for simplicity, all combinators are non-contextual,
//! which means the `State` and `Heap` types are `()`.
//!
//! To specify the `State` and `Heap` types, you can use the [`contextual`] macro,
//! which will override all provided combinators to be contextual.
//! ```
//! # use whitehole::{combinator::{contextual, Combinator}, action::Action};
//! # pub struct MyState { value: i32 }
//! # pub struct MyHeap;
//! # fn t(_: Combinator<impl Action<Text = str>>) {}
//! // Override all provided combinators to be contextual
//! contextual!(MyState, MyHeap);
//! # fn main() {
//! # t(
//! // Access the state and heap in the combinator
//! eat("true").prepare(|input| input.state.value = 1)
//! # );
//! # }
//! ```
//! See [`contextual`] for more information.
pub use cratecontextual;
pub use *;
pub use *;
use crate::;
/// Wrap an [`Action`] to provide decorators and operator overloads.
///
/// See the [module-level documentation](self) for more information.
unsafe