/rust/registry/src/index.crates.io-6f17d22bba15001f/nom-7.1.3/src/branch/mod.rs
Line | Count | Source (jump to first uncovered line) |
1 | | //! Choice combinators |
2 | | |
3 | | #[cfg(test)] |
4 | | mod tests; |
5 | | |
6 | | use crate::error::ErrorKind; |
7 | | use crate::error::ParseError; |
8 | | use crate::internal::{Err, IResult, Parser}; |
9 | | |
10 | | /// Helper trait for the [alt()] combinator. |
11 | | /// |
12 | | /// This trait is implemented for tuples of up to 21 elements |
13 | | pub trait Alt<I, O, E> { |
14 | | /// Tests each parser in the tuple and returns the result of the first one that succeeds |
15 | | fn choice(&mut self, input: I) -> IResult<I, O, E>; |
16 | | } |
17 | | |
18 | | /// Tests a list of parsers one by one until one succeeds. |
19 | | /// |
20 | | /// It takes as argument a tuple of parsers. There is a maximum of 21 |
21 | | /// parsers. If you need more, it is possible to nest them in other `alt` calls, |
22 | | /// like this: `alt(parser_a, alt(parser_b, parser_c))` |
23 | | /// |
24 | | /// ```rust |
25 | | /// # use nom::error_position; |
26 | | /// # use nom::{Err,error::ErrorKind, Needed, IResult}; |
27 | | /// use nom::character::complete::{alpha1, digit1}; |
28 | | /// use nom::branch::alt; |
29 | | /// # fn main() { |
30 | | /// fn parser(input: &str) -> IResult<&str, &str> { |
31 | | /// alt((alpha1, digit1))(input) |
32 | | /// }; |
33 | | /// |
34 | | /// // the first parser, alpha1, recognizes the input |
35 | | /// assert_eq!(parser("abc"), Ok(("", "abc"))); |
36 | | /// |
37 | | /// // the first parser returns an error, so alt tries the second one |
38 | | /// assert_eq!(parser("123456"), Ok(("", "123456"))); |
39 | | /// |
40 | | /// // both parsers failed, and with the default error type, alt will return the last error |
41 | | /// assert_eq!(parser(" "), Err(Err::Error(error_position!(" ", ErrorKind::Digit)))); |
42 | | /// # } |
43 | | /// ``` |
44 | | /// |
45 | | /// With a custom error type, it is possible to have alt return the error of the parser |
46 | | /// that went the farthest in the input data |
47 | 0 | pub fn alt<I: Clone, O, E: ParseError<I>, List: Alt<I, O, E>>( |
48 | 0 | mut l: List, |
49 | 0 | ) -> impl FnMut(I) -> IResult<I, O, E> { |
50 | 0 | move |i: I| l.choice(i) Unexecuted instantiation: nom::branch::alt::<&str, &str, nom::error::Error<&str>, (nom::character::complete::line_ending<&str, nom::error::Error<&str>>, nom::combinator::eof<&str, nom::error::Error<&str>>)>::{closure#0} Unexecuted instantiation: nom::branch::alt::<_, _, _, _>::{closure#0} |
51 | 0 | } Unexecuted instantiation: nom::branch::alt::<&str, &str, nom::error::Error<&str>, (nom::character::complete::line_ending<&str, nom::error::Error<&str>>, nom::combinator::eof<&str, nom::error::Error<&str>>)> Unexecuted instantiation: nom::branch::alt::<_, _, _, _> |
52 | | |
53 | | /// Helper trait for the [permutation()] combinator. |
54 | | /// |
55 | | /// This trait is implemented for tuples of up to 21 elements |
56 | | pub trait Permutation<I, O, E> { |
57 | | /// Tries to apply all parsers in the tuple in various orders until all of them succeed |
58 | | fn permutation(&mut self, input: I) -> IResult<I, O, E>; |
59 | | } |
60 | | |
61 | | /// Applies a list of parsers in any order. |
62 | | /// |
63 | | /// Permutation will succeed if all of the child parsers succeeded. |
64 | | /// It takes as argument a tuple of parsers, and returns a |
65 | | /// tuple of the parser results. |
66 | | /// |
67 | | /// ```rust |
68 | | /// # use nom::{Err,error::{Error, ErrorKind}, Needed, IResult}; |
69 | | /// use nom::character::complete::{alpha1, digit1}; |
70 | | /// use nom::branch::permutation; |
71 | | /// # fn main() { |
72 | | /// fn parser(input: &str) -> IResult<&str, (&str, &str)> { |
73 | | /// permutation((alpha1, digit1))(input) |
74 | | /// } |
75 | | /// |
76 | | /// // permutation recognizes alphabetic characters then digit |
77 | | /// assert_eq!(parser("abc123"), Ok(("", ("abc", "123")))); |
78 | | /// |
79 | | /// // but also in inverse order |
80 | | /// assert_eq!(parser("123abc"), Ok(("", ("abc", "123")))); |
81 | | /// |
82 | | /// // it will fail if one of the parsers failed |
83 | | /// assert_eq!(parser("abc;"), Err(Err::Error(Error::new(";", ErrorKind::Digit)))); |
84 | | /// # } |
85 | | /// ``` |
86 | | /// |
87 | | /// The parsers are applied greedily: if there are multiple unapplied parsers |
88 | | /// that could parse the next slice of input, the first one is used. |
89 | | /// ```rust |
90 | | /// # use nom::{Err, error::{Error, ErrorKind}, IResult}; |
91 | | /// use nom::branch::permutation; |
92 | | /// use nom::character::complete::{anychar, char}; |
93 | | /// |
94 | | /// fn parser(input: &str) -> IResult<&str, (char, char)> { |
95 | | /// permutation((anychar, char('a')))(input) |
96 | | /// } |
97 | | /// |
98 | | /// // anychar parses 'b', then char('a') parses 'a' |
99 | | /// assert_eq!(parser("ba"), Ok(("", ('b', 'a')))); |
100 | | /// |
101 | | /// // anychar parses 'a', then char('a') fails on 'b', |
102 | | /// // even though char('a') followed by anychar would succeed |
103 | | /// assert_eq!(parser("ab"), Err(Err::Error(Error::new("b", ErrorKind::Char)))); |
104 | | /// ``` |
105 | | /// |
106 | 0 | pub fn permutation<I: Clone, O, E: ParseError<I>, List: Permutation<I, O, E>>( |
107 | 0 | mut l: List, |
108 | 0 | ) -> impl FnMut(I) -> IResult<I, O, E> { |
109 | 0 | move |i: I| l.permutation(i) |
110 | 0 | } |
111 | | |
112 | | macro_rules! alt_trait( |
113 | | ($first:ident $second:ident $($id: ident)+) => ( |
114 | | alt_trait!(__impl $first $second; $($id)+); |
115 | | ); |
116 | | (__impl $($current:ident)*; $head:ident $($id: ident)+) => ( |
117 | | alt_trait_impl!($($current)*); |
118 | | |
119 | | alt_trait!(__impl $($current)* $head; $($id)+); |
120 | | ); |
121 | | (__impl $($current:ident)*; $head:ident) => ( |
122 | | alt_trait_impl!($($current)*); |
123 | | alt_trait_impl!($($current)* $head); |
124 | | ); |
125 | | ); |
126 | | |
127 | | macro_rules! alt_trait_impl( |
128 | | ($($id:ident)+) => ( |
129 | | impl< |
130 | | Input: Clone, Output, Error: ParseError<Input>, |
131 | | $($id: Parser<Input, Output, Error>),+ |
132 | | > Alt<Input, Output, Error> for ( $($id),+ ) { |
133 | | |
134 | 0 | fn choice(&mut self, input: Input) -> IResult<Input, Output, Error> { |
135 | 0 | match self.0.parse(input.clone()) { |
136 | 0 | Err(Err::Error(e)) => alt_trait_inner!(1, self, input, e, $($id)+), |
137 | 0 | res => res, |
138 | | } |
139 | 0 | } Unexecuted instantiation: <(nom::character::complete::line_ending<&str, nom::error::Error<&str>>, nom::combinator::eof<&str, nom::error::Error<&str>>) as nom::branch::Alt<&str, &str, nom::error::Error<&str>>>::choice Unexecuted instantiation: <(_, _) as nom::branch::Alt<_, _, _>>::choice Unexecuted instantiation: <(_, _, _) as nom::branch::Alt<_, _, _>>::choice Unexecuted instantiation: <(_, _, _, _) as nom::branch::Alt<_, _, _>>::choice Unexecuted instantiation: <(_, _, _, _, _) as nom::branch::Alt<_, _, _>>::choice Unexecuted instantiation: <(_, _, _, _, _, _) as nom::branch::Alt<_, _, _>>::choice Unexecuted instantiation: <(_, _, _, _, _, _, _) as nom::branch::Alt<_, _, _>>::choice Unexecuted instantiation: <(_, _, _, _, _, _, _, _) as nom::branch::Alt<_, _, _>>::choice Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _) as nom::branch::Alt<_, _, _>>::choice Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _) as nom::branch::Alt<_, _, _>>::choice Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _) as nom::branch::Alt<_, _, _>>::choice Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _, _) as nom::branch::Alt<_, _, _>>::choice Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _, _, _) as nom::branch::Alt<_, _, _>>::choice Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _, _, _, _) as nom::branch::Alt<_, _, _>>::choice Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _) as nom::branch::Alt<_, _, _>>::choice Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) as nom::branch::Alt<_, _, _>>::choice Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) as nom::branch::Alt<_, _, _>>::choice Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) as nom::branch::Alt<_, _, _>>::choice Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) as nom::branch::Alt<_, _, _>>::choice Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) as nom::branch::Alt<_, _, _>>::choice Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) as nom::branch::Alt<_, _, _>>::choice |
140 | | } |
141 | | ); |
142 | | ); |
143 | | |
144 | | macro_rules! alt_trait_inner( |
145 | | ($it:tt, $self:expr, $input:expr, $err:expr, $head:ident $($id:ident)+) => ( |
146 | | match $self.$it.parse($input.clone()) { |
147 | | Err(Err::Error(e)) => { |
148 | | let err = $err.or(e); |
149 | | succ!($it, alt_trait_inner!($self, $input, err, $($id)+)) |
150 | | } |
151 | | res => res, |
152 | | } |
153 | | ); |
154 | | ($it:tt, $self:expr, $input:expr, $err:expr, $head:ident) => ( |
155 | | Err(Err::Error(Error::append($input, ErrorKind::Alt, $err))) |
156 | | ); |
157 | | ); |
158 | | |
159 | | alt_trait!(A B C D E F G H I J K L M N O P Q R S T U); |
160 | | |
161 | | // Manually implement Alt for (A,), the 1-tuple type |
162 | | impl<Input, Output, Error: ParseError<Input>, A: Parser<Input, Output, Error>> |
163 | | Alt<Input, Output, Error> for (A,) |
164 | | { |
165 | 0 | fn choice(&mut self, input: Input) -> IResult<Input, Output, Error> { |
166 | 0 | self.0.parse(input) |
167 | 0 | } |
168 | | } |
169 | | |
170 | | macro_rules! permutation_trait( |
171 | | ( |
172 | | $name1:ident $ty1:ident $item1:ident |
173 | | $name2:ident $ty2:ident $item2:ident |
174 | | $($name3:ident $ty3:ident $item3:ident)* |
175 | | ) => ( |
176 | | permutation_trait!(__impl $name1 $ty1 $item1, $name2 $ty2 $item2; $($name3 $ty3 $item3)*); |
177 | | ); |
178 | | ( |
179 | | __impl $($name:ident $ty:ident $item:ident),+; |
180 | | $name1:ident $ty1:ident $item1:ident $($name2:ident $ty2:ident $item2:ident)* |
181 | | ) => ( |
182 | | permutation_trait_impl!($($name $ty $item),+); |
183 | | permutation_trait!(__impl $($name $ty $item),+ , $name1 $ty1 $item1; $($name2 $ty2 $item2)*); |
184 | | ); |
185 | | (__impl $($name:ident $ty:ident $item:ident),+;) => ( |
186 | | permutation_trait_impl!($($name $ty $item),+); |
187 | | ); |
188 | | ); |
189 | | |
190 | | macro_rules! permutation_trait_impl( |
191 | | ($($name:ident $ty:ident $item:ident),+) => ( |
192 | | impl< |
193 | | Input: Clone, $($ty),+ , Error: ParseError<Input>, |
194 | | $($name: Parser<Input, $ty, Error>),+ |
195 | | > Permutation<Input, ( $($ty),+ ), Error> for ( $($name),+ ) { |
196 | | |
197 | 0 | fn permutation(&mut self, mut input: Input) -> IResult<Input, ( $($ty),+ ), Error> { |
198 | 0 | let mut res = ($(Option::<$ty>::None),+); |
199 | | |
200 | | loop { |
201 | 0 | let mut err: Option<Error> = None; |
202 | 0 | permutation_trait_inner!(0, self, input, res, err, $($name)+); |
203 | | |
204 | | // If we reach here, every iterator has either been applied before, |
205 | | // or errored on the remaining input |
206 | 0 | if let Some(err) = err { |
207 | | // There are remaining parsers, and all errored on the remaining input |
208 | 0 | return Err(Err::Error(Error::append(input, ErrorKind::Permutation, err))); |
209 | 0 | } |
210 | | |
211 | | // All parsers were applied |
212 | 0 | match res { |
213 | 0 | ($(Some($item)),+) => return Ok((input, ($($item),+))), |
214 | 0 | _ => unreachable!(), |
215 | | } |
216 | | } |
217 | 0 | } Unexecuted instantiation: <(_, _) as nom::branch::Permutation<_, (_, _), _>>::permutation Unexecuted instantiation: <(_, _, _) as nom::branch::Permutation<_, (_, _, _), _>>::permutation Unexecuted instantiation: <(_, _, _, _) as nom::branch::Permutation<_, (_, _, _, _), _>>::permutation Unexecuted instantiation: <(_, _, _, _, _) as nom::branch::Permutation<_, (_, _, _, _, _), _>>::permutation Unexecuted instantiation: <(_, _, _, _, _, _) as nom::branch::Permutation<_, (_, _, _, _, _, _), _>>::permutation Unexecuted instantiation: <(_, _, _, _, _, _, _) as nom::branch::Permutation<_, (_, _, _, _, _, _, _), _>>::permutation Unexecuted instantiation: <(_, _, _, _, _, _, _, _) as nom::branch::Permutation<_, (_, _, _, _, _, _, _, _), _>>::permutation Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _) as nom::branch::Permutation<_, (_, _, _, _, _, _, _, _, _), _>>::permutation Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _) as nom::branch::Permutation<_, (_, _, _, _, _, _, _, _, _, _), _>>::permutation Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _) as nom::branch::Permutation<_, (_, _, _, _, _, _, _, _, _, _, _), _>>::permutation Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _, _) as nom::branch::Permutation<_, (_, _, _, _, _, _, _, _, _, _, _, _), _>>::permutation Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _, _, _) as nom::branch::Permutation<_, (_, _, _, _, _, _, _, _, _, _, _, _, _), _>>::permutation Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _, _, _, _) as nom::branch::Permutation<_, (_, _, _, _, _, _, _, _, _, _, _, _, _, _), _>>::permutation Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _) as nom::branch::Permutation<_, (_, _, _, _, _, _, _, _, _, _, _, _, _, _, _), _>>::permutation Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) as nom::branch::Permutation<_, (_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _), _>>::permutation Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) as nom::branch::Permutation<_, (_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _), _>>::permutation Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) as nom::branch::Permutation<_, (_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _), _>>::permutation Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) as nom::branch::Permutation<_, (_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _), _>>::permutation Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) as nom::branch::Permutation<_, (_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _), _>>::permutation Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) as nom::branch::Permutation<_, (_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _), _>>::permutation |
218 | | } |
219 | | ); |
220 | | ); |
221 | | |
222 | | macro_rules! permutation_trait_inner( |
223 | | ($it:tt, $self:expr, $input:ident, $res:expr, $err:expr, $head:ident $($id:ident)*) => ( |
224 | | if $res.$it.is_none() { |
225 | | match $self.$it.parse($input.clone()) { |
226 | | Ok((i, o)) => { |
227 | | $input = i; |
228 | | $res.$it = Some(o); |
229 | | continue; |
230 | | } |
231 | | Err(Err::Error(e)) => { |
232 | | $err = Some(match $err { |
233 | | Some(err) => err.or(e), |
234 | | None => e, |
235 | | }); |
236 | | } |
237 | | Err(e) => return Err(e), |
238 | | }; |
239 | | } |
240 | | succ!($it, permutation_trait_inner!($self, $input, $res, $err, $($id)*)); |
241 | | ); |
242 | | ($it:tt, $self:expr, $input:ident, $res:expr, $err:expr,) => (); |
243 | | ); |
244 | | |
245 | | permutation_trait!( |
246 | | FnA A a |
247 | | FnB B b |
248 | | FnC C c |
249 | | FnD D d |
250 | | FnE E e |
251 | | FnF F f |
252 | | FnG G g |
253 | | FnH H h |
254 | | FnI I i |
255 | | FnJ J j |
256 | | FnK K k |
257 | | FnL L l |
258 | | FnM M m |
259 | | FnN N n |
260 | | FnO O o |
261 | | FnP P p |
262 | | FnQ Q q |
263 | | FnR R r |
264 | | FnS S s |
265 | | FnT T t |
266 | | FnU U u |
267 | | ); |