1 // Copyright 2018 Syn Developers
2 //
3 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6 // option. This file may not be copied, modified, or distributed
7 // except according to those terms.
8 
9 use buffer::Cursor;
10 use parse_error;
11 use synom::PResult;
12 
13 /// Define a parser function with the signature expected by syn parser
14 /// combinators.
15 ///
16 /// The function may be the `parse` function of the [`Synom`] trait, or it may
17 /// be a free-standing function with an arbitrary name. When implementing the
18 /// `Synom` trait, the function name is `parse` and the return type is `Self`.
19 ///
20 /// [`Synom`]: synom/trait.Synom.html
21 ///
22 /// - **Syntax:** `named!(NAME -> TYPE, PARSER)` or `named!(pub NAME -> TYPE, PARSER)`
23 ///
24 /// ```rust
25 /// #[macro_use]
26 /// extern crate syn;
27 ///
28 /// use syn::Type;
29 /// use syn::punctuated::Punctuated;
30 /// use syn::synom::Synom;
31 ///
32 /// /// Parses one or more Rust types separated by commas.
33 /// ///
34 /// /// Example: `String, Vec<T>, [u8; LEN + 1]`
35 /// named!(pub comma_separated_types -> Punctuated<Type, Token![,]>,
36 ///     call!(Punctuated::parse_separated_nonempty)
37 /// );
38 ///
39 /// /// The same function as a `Synom` implementation.
40 /// struct CommaSeparatedTypes {
41 ///     types: Punctuated<Type, Token![,]>,
42 /// }
43 ///
44 /// impl Synom for CommaSeparatedTypes {
45 ///     /// As the default behavior, we want there to be at least 1 type.
46 ///     named!(parse -> Self, do_parse!(
47 ///         types: call!(Punctuated::parse_separated_nonempty) >>
48 ///         (CommaSeparatedTypes { types })
49 ///     ));
50 /// }
51 ///
52 /// impl CommaSeparatedTypes {
53 ///     /// A separate parser that the user can invoke explicitly which allows
54 ///     /// for parsing 0 or more types, rather than the default 1 or more.
55 ///     named!(pub parse0 -> Self, do_parse!(
56 ///         types: call!(Punctuated::parse_separated) >>
57 ///         (CommaSeparatedTypes { types })
58 ///     ));
59 /// }
60 /// #
61 /// # fn main() {}
62 /// ```
63 ///
64 /// *This macro is available if Syn is built with the `"parsing"` feature.*
65 #[macro_export]
66 macro_rules! named {
67     ($name:ident -> $o:ty, $submac:ident!( $($args:tt)* )) => {
68         fn $name(i: $crate::buffer::Cursor) -> $crate::synom::PResult<$o> {
69             $submac!(i, $($args)*)
70         }
71     };
72 
73     (pub $name:ident -> $o:ty, $submac:ident!( $($args:tt)* )) => {
74         pub fn $name(i: $crate::buffer::Cursor) -> $crate::synom::PResult<$o> {
75             $submac!(i, $($args)*)
76         }
77     };
78 
79     // These two variants are for defining named parsers which have custom
80     // arguments, and are called with `call!()`
81     ($name:ident($($params:tt)*) -> $o:ty, $submac:ident!( $($args:tt)* )) => {
82         fn $name(i: $crate::buffer::Cursor, $($params)*) -> $crate::synom::PResult<$o> {
83             $submac!(i, $($args)*)
84         }
85     };
86 
87     (pub $name:ident($($params:tt)*) -> $o:ty, $submac:ident!( $($args:tt)* )) => {
88         pub fn $name(i: $crate::buffer::Cursor, $($params)*) -> $crate::synom::PResult<$o> {
89             $submac!(i, $($args)*)
90         }
91     };
92 }
93 
94 #[cfg(synom_verbose_trace)]
95 #[macro_export]
96 macro_rules! call {
97     ($i:expr, $fun:expr $(, $args:expr)*) => {{
98         let i = $i;
99         eprintln!(concat!(" -> ", stringify!($fun), " @ {:?}"), i);
100         let r = $fun(i $(, $args)*);
101         match r {
102             Ok((_, i)) => eprintln!(concat!("OK  ", stringify!($fun), " @ {:?}"), i),
103             Err(_) => eprintln!(concat!("ERR ", stringify!($fun), " @ {:?}"), i),
104         }
105         r
106     }};
107 }
108 
109 /// Invoke the given parser function with zero or more arguments.
110 ///
111 /// - **Syntax:** `call!(FN, ARGS...)`
112 ///
113 ///   where the signature of the function is `fn(Cursor, ARGS...) -> PResult<T>`
114 ///
115 /// - **Output:** `T`, the result of invoking the function `FN`
116 ///
117 /// ```rust
118 /// #[macro_use]
119 /// extern crate syn;
120 ///
121 /// use syn::Type;
122 /// use syn::punctuated::Punctuated;
123 /// use syn::synom::Synom;
124 ///
125 /// /// Parses one or more Rust types separated by commas.
126 /// ///
127 /// /// Example: `String, Vec<T>, [u8; LEN + 1]`
128 /// struct CommaSeparatedTypes {
129 ///     types: Punctuated<Type, Token![,]>,
130 /// }
131 ///
132 /// impl Synom for CommaSeparatedTypes {
133 ///     named!(parse -> Self, do_parse!(
134 ///         types: call!(Punctuated::parse_separated_nonempty) >>
135 ///         (CommaSeparatedTypes { types })
136 ///     ));
137 /// }
138 /// #
139 /// # fn main() {}
140 /// ```
141 ///
142 /// *This macro is available if Syn is built with the `"parsing"` feature.*
143 #[cfg(not(synom_verbose_trace))]
144 #[macro_export]
145 macro_rules! call {
146     ($i:expr, $fun:expr $(, $args:expr)*) => {
147         $fun($i $(, $args)*)
148     };
149 }
150 
151 /// Transform the result of a parser by applying a function or closure.
152 ///
153 /// - **Syntax:** `map!(THING, FN)`
154 /// - **Output:** the return type of function FN applied to THING
155 ///
156 /// ```rust
157 /// #[macro_use]
158 /// extern crate syn;
159 ///
160 /// use syn::{Expr, ExprIf};
161 ///
162 /// /// Extracts the branch condition of an `if`-expression.
163 /// fn get_cond(if_: ExprIf) -> Expr {
164 ///     *if_.cond
165 /// }
166 ///
167 /// /// Parses a full `if`-expression but returns the condition part only.
168 /// ///
169 /// /// Example: `if x > 0xFF { "big" } else { "small" }`
170 /// /// The return would be the expression `x > 0xFF`.
171 /// named!(if_condition -> Expr,
172 ///     map!(syn!(ExprIf), get_cond)
173 /// );
174 ///
175 /// /// Equivalent using a closure.
176 /// named!(if_condition2 -> Expr,
177 ///     map!(syn!(ExprIf), |if_| *if_.cond)
178 /// );
179 /// #
180 /// # fn main() {}
181 /// ```
182 ///
183 /// *This macro is available if Syn is built with the `"parsing"` feature.*
184 #[macro_export]
185 macro_rules! map {
186     ($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => {
187         match $submac!($i, $($args)*) {
188             ::std::result::Result::Err(err) =>
189                 ::std::result::Result::Err(err),
190             ::std::result::Result::Ok((o, i)) =>
191                 ::std::result::Result::Ok(($crate::parsers::invoke($g, o), i)),
192         }
193     };
194 
195     ($i:expr, $f:expr, $g:expr) => {
196         map!($i, call!($f), $g)
197     };
198 }
199 
200 // Somehow this helps with type inference in `map!` and `alt!`.
201 //
202 // Not public API.
203 #[doc(hidden)]
invoke<T, R, F: FnOnce(T) -> R>(f: F, t: T) -> R204 pub fn invoke<T, R, F: FnOnce(T) -> R>(f: F, t: T) -> R {
205     f(t)
206 }
207 
208 /// Invert the result of a parser by parsing successfully if the given parser
209 /// fails to parse and vice versa.
210 ///
211 /// Does not consume any of the input.
212 ///
213 /// - **Syntax:** `not!(THING)`
214 /// - **Output:** `()`
215 ///
216 /// ```rust
217 /// #[macro_use]
218 /// extern crate syn;
219 ///
220 /// use syn::{Expr, Ident};
221 ///
222 /// /// Parses any expression that does not begin with a `-` minus sign.
223 /// named!(not_negative_expr -> Expr, do_parse!(
224 ///     not!(punct!(-)) >>
225 ///     e: syn!(Expr) >>
226 ///     (e)
227 /// ));
228 /// #
229 /// # fn main() {}
230 /// ```
231 ///
232 /// *This macro is available if Syn is built with the `"parsing"` feature.*
233 #[macro_export]
234 macro_rules! not {
235     ($i:expr, $submac:ident!( $($args:tt)* )) => {
236         match $submac!($i, $($args)*) {
237             ::std::result::Result::Ok(_) => $crate::parse_error(),
238             ::std::result::Result::Err(_) =>
239                 ::std::result::Result::Ok(((), $i)),
240         }
241     };
242 }
243 
244 /// Execute a parser only if a condition is met, otherwise return None.
245 ///
246 /// If you are familiar with nom, this is nom's `cond_with_error` parser.
247 ///
248 /// - **Syntax:** `cond!(CONDITION, THING)`
249 /// - **Output:** `Some(THING)` if the condition is true, else `None`
250 ///
251 /// ```rust
252 /// #[macro_use]
253 /// extern crate syn;
254 ///
255 /// use syn::{Ident, MacroDelimiter};
256 /// use syn::token::{Paren, Bracket, Brace};
257 /// use syn::synom::Synom;
258 ///
259 /// /// Parses a macro call with empty input. If the macro is written with
260 /// /// parentheses or brackets, a trailing semicolon is required.
261 /// ///
262 /// /// Example: `my_macro!{}` or `my_macro!();` or `my_macro![];`
263 /// struct EmptyMacroCall {
264 ///     name: Ident,
265 ///     bang_token: Token![!],
266 ///     empty_body: MacroDelimiter,
267 ///     semi_token: Option<Token![;]>,
268 /// }
269 ///
270 /// fn requires_semi(delimiter: &MacroDelimiter) -> bool {
271 ///     match *delimiter {
272 ///         MacroDelimiter::Paren(_) | MacroDelimiter::Bracket(_) => true,
273 ///         MacroDelimiter::Brace(_) => false,
274 ///     }
275 /// }
276 ///
277 /// impl Synom for EmptyMacroCall {
278 ///     named!(parse -> Self, do_parse!(
279 ///         name: syn!(Ident) >>
280 ///         bang_token: punct!(!) >>
281 ///         empty_body: alt!(
282 ///             parens!(epsilon!()) => { |d| MacroDelimiter::Paren(d.0) }
283 ///             |
284 ///             brackets!(epsilon!()) => { |d| MacroDelimiter::Bracket(d.0) }
285 ///             |
286 ///             braces!(epsilon!()) => { |d| MacroDelimiter::Brace(d.0) }
287 ///         ) >>
288 ///         semi_token: cond!(requires_semi(&empty_body), punct!(;)) >>
289 ///         (EmptyMacroCall {
290 ///             name,
291 ///             bang_token,
292 ///             empty_body,
293 ///             semi_token,
294 ///         })
295 ///     ));
296 /// }
297 /// #
298 /// # fn main() {}
299 /// ```
300 ///
301 /// *This macro is available if Syn is built with the `"parsing"` feature.*
302 #[macro_export]
303 macro_rules! cond {
304     ($i:expr, $cond:expr, $submac:ident!( $($args:tt)* )) => {
305         if $cond {
306             match $submac!($i, $($args)*) {
307                 ::std::result::Result::Ok((o, i)) =>
308                     ::std::result::Result::Ok((::std::option::Option::Some(o), i)),
309                 ::std::result::Result::Err(x) => ::std::result::Result::Err(x),
310             }
311         } else {
312             ::std::result::Result::Ok((::std::option::Option::None, $i))
313         }
314     };
315 
316     ($i:expr, $cond:expr, $f:expr) => {
317         cond!($i, $cond, call!($f))
318     };
319 }
320 
321 /// Execute a parser only if a condition is met, otherwise fail to parse.
322 ///
323 /// This is typically used inside of [`option!`] or [`alt!`].
324 ///
325 /// [`option!`]: macro.option.html
326 /// [`alt!`]: macro.alt.html
327 ///
328 /// - **Syntax:** `cond_reduce!(CONDITION, THING)`
329 /// - **Output:** `THING`
330 ///
331 /// The subparser may be omitted in which case it defaults to [`epsilon!`].
332 ///
333 /// [`epsilon!`]: macro.epsilon.html
334 ///
335 /// - **Syntax:** `cond_reduce!(CONDITION)`
336 /// - **Output:** `()`
337 ///
338 /// ```rust
339 /// #[macro_use]
340 /// extern crate syn;
341 ///
342 /// use syn::Type;
343 /// use syn::token::Paren;
344 /// use syn::punctuated::Punctuated;
345 /// use syn::synom::Synom;
346 ///
347 /// /// Parses a possibly variadic function signature.
348 /// ///
349 /// /// Example: `fn(A) or `fn(A, B, C, ...)` or `fn(...)`
350 /// /// Rejected: `fn(A, B...)`
351 /// struct VariadicFn {
352 ///     fn_token: Token![fn],
353 ///     paren_token: Paren,
354 ///     types: Punctuated<Type, Token![,]>,
355 ///     variadic: Option<Token![...]>,
356 /// }
357 ///
358 /// // Example of using `cond_reduce!` inside of `option!`.
359 /// impl Synom for VariadicFn {
360 ///     named!(parse -> Self, do_parse!(
361 ///         fn_token: keyword!(fn) >>
362 ///         params: parens!(do_parse!(
363 ///             types: call!(Punctuated::parse_terminated) >>
364 ///             // Allow, but do not require, an ending `...` but only if the
365 ///             // preceding list of types is empty or ends with a trailing comma.
366 ///             variadic: option!(cond_reduce!(types.empty_or_trailing(), punct!(...))) >>
367 ///             (types, variadic)
368 ///         )) >>
369 ///         ({
370 ///             let (paren_token, (types, variadic)) = params;
371 ///             VariadicFn {
372 ///                 fn_token,
373 ///                 paren_token,
374 ///                 types,
375 ///                 variadic,
376 ///             }
377 ///         })
378 ///     ));
379 /// }
380 /// #
381 /// # fn main() {}
382 /// ```
383 ///
384 /// *This macro is available if Syn is built with the `"parsing"` feature.*
385 #[macro_export]
386 macro_rules! cond_reduce {
387     ($i:expr, $cond:expr, $submac:ident!( $($args:tt)* )) => {
388         if $cond {
389             $submac!($i, $($args)*)
390         } else {
391             $crate::parse_error()
392         }
393     };
394 
395     ($i:expr, $cond:expr) => {
396         cond_reduce!($i, $cond, epsilon!())
397     };
398 
399     ($i:expr, $cond:expr, $f:expr) => {
400         cond_reduce!($i, $cond, call!($f))
401     };
402 }
403 
404 /// Parse zero or more values using the given parser.
405 ///
406 /// - **Syntax:** `many0!(THING)`
407 /// - **Output:** `Vec<THING>`
408 ///
409 /// You may also be looking for:
410 ///
411 /// - `call!(Punctuated::parse_separated)` - zero or more values with separator
412 /// - `call!(Punctuated::parse_separated_nonempty)` - one or more values
413 /// - `call!(Punctuated::parse_terminated)` - zero or more, allows trailing separator
414 /// - `call!(Punctuated::parse_terminated_nonempty)` - one or more
415 ///
416 /// ```rust
417 /// #[macro_use]
418 /// extern crate syn;
419 ///
420 /// use syn::{Ident, Item};
421 /// use syn::token::Brace;
422 /// use syn::synom::Synom;
423 ///
424 /// /// Parses a module containing zero or more Rust items.
425 /// ///
426 /// /// Example: `mod m { type Result<T> = ::std::result::Result<T, MyError>; }`
427 /// struct SimpleMod {
428 ///     mod_token: Token![mod],
429 ///     name: Ident,
430 ///     brace_token: Brace,
431 ///     items: Vec<Item>,
432 /// }
433 ///
434 /// impl Synom for SimpleMod {
435 ///     named!(parse -> Self, do_parse!(
436 ///         mod_token: keyword!(mod) >>
437 ///         name: syn!(Ident) >>
438 ///         body: braces!(many0!(syn!(Item))) >>
439 ///         (SimpleMod {
440 ///             mod_token,
441 ///             name,
442 ///             brace_token: body.0,
443 ///             items: body.1,
444 ///         })
445 ///     ));
446 /// }
447 /// #
448 /// # fn main() {}
449 /// ```
450 ///
451 /// *This macro is available if Syn is built with the `"parsing"` feature.*
452 #[macro_export]
453 macro_rules! many0 {
454     ($i:expr, $submac:ident!( $($args:tt)* )) => {{
455         let ret;
456         let mut res   = ::std::vec::Vec::new();
457         let mut input = $i;
458 
459         loop {
460             if input.eof() {
461                 ret = ::std::result::Result::Ok((res, input));
462                 break;
463             }
464 
465             match $submac!(input, $($args)*) {
466                 ::std::result::Result::Err(_) => {
467                     ret = ::std::result::Result::Ok((res, input));
468                     break;
469                 }
470                 ::std::result::Result::Ok((o, i)) => {
471                     // loop trip must always consume (otherwise infinite loops)
472                     if i == input {
473                         ret = $crate::parse_error();
474                         break;
475                     }
476 
477                     res.push(o);
478                     input = i;
479                 }
480             }
481         }
482 
483         ret
484     }};
485 
486     ($i:expr, $f:expr) => {
487         $crate::parsers::many0($i, $f)
488     };
489 }
490 
491 // Improve compile time by compiling this loop only once per type it is used
492 // with.
493 //
494 // Not public API.
495 #[doc(hidden)]
many0<T>(mut input: Cursor, f: fn(Cursor) -> PResult<T>) -> PResult<Vec<T>>496 pub fn many0<T>(mut input: Cursor, f: fn(Cursor) -> PResult<T>) -> PResult<Vec<T>> {
497     let mut res = Vec::new();
498 
499     loop {
500         if input.eof() {
501             return Ok((res, input));
502         }
503 
504         match f(input) {
505             Err(_) => {
506                 return Ok((res, input));
507             }
508             Ok((o, i)) => {
509                 // loop trip must always consume (otherwise infinite loops)
510                 if i == input {
511                     return parse_error();
512                 }
513 
514                 res.push(o);
515                 input = i;
516             }
517         }
518     }
519 }
520 
521 /// Pattern-match the result of a parser to select which other parser to run.
522 ///
523 /// - **Syntax:** `switch!(TARGET, PAT1 => THEN1 | PAT2 => THEN2 | ...)`
524 /// - **Output:** `T`, the return type of `THEN1` and `THEN2` and ...
525 ///
526 /// ```rust
527 /// #[macro_use]
528 /// extern crate syn;
529 ///
530 /// use syn::Ident;
531 /// use syn::token::Brace;
532 /// use syn::synom::Synom;
533 ///
534 /// /// Parse a unit struct or enum: either `struct S;` or `enum E { V }`.
535 /// enum UnitType {
536 ///     Struct {
537 ///         struct_token: Token![struct],
538 ///         name: Ident,
539 ///         semi_token: Token![;],
540 ///     },
541 ///     Enum {
542 ///         enum_token: Token![enum],
543 ///         name: Ident,
544 ///         brace_token: Brace,
545 ///         variant: Ident,
546 ///     },
547 /// }
548 ///
549 /// enum StructOrEnum {
550 ///     Struct(Token![struct]),
551 ///     Enum(Token![enum]),
552 /// }
553 ///
554 /// impl Synom for StructOrEnum {
555 ///     named!(parse -> Self, alt!(
556 ///         keyword!(struct) => { StructOrEnum::Struct }
557 ///         |
558 ///         keyword!(enum) => { StructOrEnum::Enum }
559 ///     ));
560 /// }
561 ///
562 /// impl Synom for UnitType {
563 ///     named!(parse -> Self, do_parse!(
564 ///         which: syn!(StructOrEnum) >>
565 ///         name: syn!(Ident) >>
566 ///         item: switch!(value!(which),
567 ///             StructOrEnum::Struct(struct_token) => map!(
568 ///                 punct!(;),
569 ///                 |semi_token| UnitType::Struct {
570 ///                     struct_token,
571 ///                     name,
572 ///                     semi_token,
573 ///                 }
574 ///             )
575 ///             |
576 ///             StructOrEnum::Enum(enum_token) => map!(
577 ///                 braces!(syn!(Ident)),
578 ///                 |(brace_token, variant)| UnitType::Enum {
579 ///                     enum_token,
580 ///                     name,
581 ///                     brace_token,
582 ///                     variant,
583 ///                 }
584 ///             )
585 ///         ) >>
586 ///         (item)
587 ///     ));
588 /// }
589 /// #
590 /// # fn main() {}
591 /// ```
592 ///
593 /// *This macro is available if Syn is built with the `"parsing"` feature.*
594 #[macro_export]
595 macro_rules! switch {
596     ($i:expr, $submac:ident!( $($args:tt)* ), $($p:pat => $subrule:ident!( $($args2:tt)* ))|* ) => {
597         match $submac!($i, $($args)*) {
598             ::std::result::Result::Err(err) => ::std::result::Result::Err(err),
599             ::std::result::Result::Ok((o, i)) => match o {
600                 $(
601                     $p => $subrule!(i, $($args2)*),
602                 )*
603             }
604         }
605     };
606 }
607 
608 /// Produce the given value without parsing anything.
609 ///
610 /// This can be needed where you have an existing parsed value but a parser
611 /// macro's syntax expects you to provide a submacro, such as in the first
612 /// argument of [`switch!`] or one of the branches of [`alt!`].
613 ///
614 /// [`switch!`]: macro.switch.html
615 /// [`alt!`]: macro.alt.html
616 ///
617 /// - **Syntax:** `value!(VALUE)`
618 /// - **Output:** `VALUE`
619 ///
620 /// ```rust
621 /// #[macro_use]
622 /// extern crate syn;
623 ///
624 /// use syn::Ident;
625 /// use syn::token::Brace;
626 /// use syn::synom::Synom;
627 ///
628 /// /// Parse a unit struct or enum: either `struct S;` or `enum E { V }`.
629 /// enum UnitType {
630 ///     Struct {
631 ///         struct_token: Token![struct],
632 ///         name: Ident,
633 ///         semi_token: Token![;],
634 ///     },
635 ///     Enum {
636 ///         enum_token: Token![enum],
637 ///         name: Ident,
638 ///         brace_token: Brace,
639 ///         variant: Ident,
640 ///     },
641 /// }
642 ///
643 /// enum StructOrEnum {
644 ///     Struct(Token![struct]),
645 ///     Enum(Token![enum]),
646 /// }
647 ///
648 /// impl Synom for StructOrEnum {
649 ///     named!(parse -> Self, alt!(
650 ///         keyword!(struct) => { StructOrEnum::Struct }
651 ///         |
652 ///         keyword!(enum) => { StructOrEnum::Enum }
653 ///     ));
654 /// }
655 ///
656 /// impl Synom for UnitType {
657 ///     named!(parse -> Self, do_parse!(
658 ///         which: syn!(StructOrEnum) >>
659 ///         name: syn!(Ident) >>
660 ///         item: switch!(value!(which),
661 ///             StructOrEnum::Struct(struct_token) => map!(
662 ///                 punct!(;),
663 ///                 |semi_token| UnitType::Struct {
664 ///                     struct_token,
665 ///                     name,
666 ///                     semi_token,
667 ///                 }
668 ///             )
669 ///             |
670 ///             StructOrEnum::Enum(enum_token) => map!(
671 ///                 braces!(syn!(Ident)),
672 ///                 |(brace_token, variant)| UnitType::Enum {
673 ///                     enum_token,
674 ///                     name,
675 ///                     brace_token,
676 ///                     variant,
677 ///                 }
678 ///             )
679 ///         ) >>
680 ///         (item)
681 ///     ));
682 /// }
683 /// #
684 /// # fn main() {}
685 /// ```
686 ///
687 /// *This macro is available if Syn is built with the `"parsing"` feature.*
688 #[macro_export]
689 macro_rules! value {
690     ($i:expr, $res:expr) => {
691         ::std::result::Result::Ok(($res, $i))
692     };
693 }
694 
695 /// Unconditionally fail to parse anything.
696 ///
697 /// This may be useful in rejecting some arms of a `switch!` parser.
698 ///
699 /// - **Syntax:** `reject!()`
700 /// - **Output:** never succeeds
701 ///
702 /// ```rust
703 /// #[macro_use]
704 /// extern crate syn;
705 ///
706 /// use syn::Item;
707 ///
708 /// // Parse any item, except for a module.
709 /// named!(almost_any_item -> Item,
710 ///     switch!(syn!(Item),
711 ///         Item::Mod(_) => reject!()
712 ///         |
713 ///         ok => value!(ok)
714 ///     )
715 /// );
716 /// #
717 /// # fn main() {}
718 /// ```
719 ///
720 /// *This macro is available if Syn is built with the `"parsing"` feature.*
721 #[macro_export]
722 macro_rules! reject {
723     ($i:expr,) => {{
724         let _ = $i;
725         $crate::parse_error()
726     }}
727 }
728 
729 /// Run a series of parsers and produce all of the results in a tuple.
730 ///
731 /// - **Syntax:** `tuple!(A, B, C, ...)`
732 /// - **Output:** `(A, B, C, ...)`
733 ///
734 /// ```rust
735 /// #[macro_use]
736 /// extern crate syn;
737 ///
738 /// use syn::Type;
739 ///
740 /// named!(two_types -> (Type, Type), tuple!(syn!(Type), syn!(Type)));
741 /// #
742 /// # fn main() {}
743 /// ```
744 ///
745 /// *This macro is available if Syn is built with the `"parsing"` feature.*
746 #[macro_export]
747 macro_rules! tuple {
748     ($i:expr, $($rest:tt)*) => {
749         tuple_parser!($i, (), $($rest)*)
750     };
751 }
752 
753 // Internal parser, do not use directly.
754 #[doc(hidden)]
755 #[macro_export]
756 macro_rules! tuple_parser {
757     ($i:expr, ($($parsed:tt),*), $e:ident, $($rest:tt)*) => {
758         tuple_parser!($i, ($($parsed),*), call!($e), $($rest)*)
759     };
760 
761     ($i:expr, (), $submac:ident!( $($args:tt)* ), $($rest:tt)*) => {
762         match $submac!($i, $($args)*) {
763             ::std::result::Result::Err(err) =>
764                 ::std::result::Result::Err(err),
765             ::std::result::Result::Ok((o, i)) =>
766                 tuple_parser!(i, (o), $($rest)*),
767         }
768     };
769 
770     ($i:expr, ($($parsed:tt)*), $submac:ident!( $($args:tt)* ), $($rest:tt)*) => {
771         match $submac!($i, $($args)*) {
772             ::std::result::Result::Err(err) =>
773                 ::std::result::Result::Err(err),
774             ::std::result::Result::Ok((o, i)) =>
775                 tuple_parser!(i, ($($parsed)* , o), $($rest)*),
776         }
777     };
778 
779     ($i:expr, ($($parsed:tt),*), $e:ident) => {
780         tuple_parser!($i, ($($parsed),*), call!($e))
781     };
782 
783     ($i:expr, (), $submac:ident!( $($args:tt)* )) => {
784         $submac!($i, $($args)*)
785     };
786 
787     ($i:expr, ($($parsed:expr),*), $submac:ident!( $($args:tt)* )) => {
788         match $submac!($i, $($args)*) {
789             ::std::result::Result::Err(err) =>
790                 ::std::result::Result::Err(err),
791             ::std::result::Result::Ok((o, i)) =>
792                 ::std::result::Result::Ok((($($parsed),*, o), i)),
793         }
794     };
795 
796     ($i:expr, ($($parsed:expr),*)) => {
797         ::std::result::Result::Ok((($($parsed),*), $i))
798     };
799 }
800 
801 /// Run a series of parsers, returning the result of the first one which
802 /// succeeds.
803 ///
804 /// Optionally allows for the result to be transformed.
805 ///
806 /// - **Syntax:** `alt!(THING1 | THING2 => { FUNC } | ...)`
807 /// - **Output:** `T`, the return type of `THING1` and `FUNC(THING2)` and ...
808 ///
809 /// # Example
810 ///
811 /// ```rust
812 /// #[macro_use]
813 /// extern crate syn;
814 ///
815 /// use syn::Ident;
816 ///
817 /// // Parse any identifier token, or the `!` token in which case the
818 /// // identifier is treated as `"BANG"`.
819 /// named!(ident_or_bang -> Ident, alt!(
820 ///     syn!(Ident)
821 ///     |
822 ///     punct!(!) => { |_| "BANG".into() }
823 /// ));
824 /// #
825 /// # fn main() {}
826 /// ```
827 ///
828 /// The `alt!` macro is most commonly seen when parsing a syntax tree enum such
829 /// as the [`Item`] enum.
830 ///
831 /// [`Item`]: enum.Item.html
832 ///
833 /// ```
834 /// # #[macro_use]
835 /// # extern crate syn;
836 /// #
837 /// # use syn::synom::Synom;
838 /// #
839 /// # struct Item;
840 /// #
841 /// impl Synom for Item {
842 ///     named!(parse -> Self, alt!(
843 /// #       epsilon!() => { |_| unimplemented!() }
844 /// #   ));
845 /// # }
846 /// #
847 /// # mod example {
848 /// #   use syn::*;
849 /// #
850 /// #   named!(parse -> Item, alt!(
851 ///         syn!(ItemExternCrate) => { Item::ExternCrate }
852 ///         |
853 ///         syn!(ItemUse) => { Item::Use }
854 ///         |
855 ///         syn!(ItemStatic) => { Item::Static }
856 ///         |
857 ///         syn!(ItemConst) => { Item::Const }
858 ///         |
859 ///         /* ... */
860 /// #       syn!(ItemFn) => { Item::Fn }
861 ///     ));
862 /// }
863 /// #
864 /// # fn main() {}
865 /// ```
866 ///
867 /// *This macro is available if Syn is built with the `"parsing"` feature.*
868 #[macro_export]
869 macro_rules! alt {
870     ($i:expr, $e:ident | $($rest:tt)*) => {
871         alt!($i, call!($e) | $($rest)*)
872     };
873 
874     ($i:expr, $subrule:ident!( $($args:tt)*) | $($rest:tt)*) => {
875         match $subrule!($i, $($args)*) {
876             res @ ::std::result::Result::Ok(_) => res,
877             _ => alt!($i, $($rest)*)
878         }
879     };
880 
881     ($i:expr, $subrule:ident!( $($args:tt)* ) => { $gen:expr } | $($rest:tt)+) => {
882         match $subrule!($i, $($args)*) {
883             ::std::result::Result::Ok((o, i)) =>
884                 ::std::result::Result::Ok(($crate::parsers::invoke($gen, o), i)),
885             ::std::result::Result::Err(_) => alt!($i, $($rest)*),
886         }
887     };
888 
889     ($i:expr, $e:ident => { $gen:expr } | $($rest:tt)*) => {
890         alt!($i, call!($e) => { $gen } | $($rest)*)
891     };
892 
893     ($i:expr, $e:ident => { $gen:expr }) => {
894         alt!($i, call!($e) => { $gen })
895     };
896 
897     ($i:expr, $subrule:ident!( $($args:tt)* ) => { $gen:expr }) => {
898         match $subrule!($i, $($args)*) {
899             ::std::result::Result::Ok((o, i)) =>
900                 ::std::result::Result::Ok(($crate::parsers::invoke($gen, o), i)),
901             ::std::result::Result::Err(err) =>
902                 ::std::result::Result::Err(err),
903         }
904     };
905 
906     ($i:expr, $e:ident) => {
907         alt!($i, call!($e))
908     };
909 
910     ($i:expr, $subrule:ident!( $($args:tt)*)) => {
911         $subrule!($i, $($args)*)
912     };
913 }
914 
915 /// Run a series of parsers, optionally naming each intermediate result,
916 /// followed by a step to combine the intermediate results.
917 ///
918 /// Produces the result of evaluating the final expression in parentheses with
919 /// all of the previously named results bound.
920 ///
921 /// - **Syntax:** `do_parse!(name: THING1 >> THING2 >> (RESULT))`
922 /// - **Output:** `RESULT`
923 ///
924 /// ```rust
925 /// #[macro_use]
926 /// extern crate syn;
927 /// extern crate proc_macro2;
928 ///
929 /// use syn::Ident;
930 /// use syn::token::Paren;
931 /// use syn::synom::Synom;
932 /// use proc_macro2::TokenStream;
933 ///
934 /// /// Parse a macro invocation that uses `(` `)` parentheses.
935 /// ///
936 /// /// Example: `stringify!($args)`.
937 /// struct Macro {
938 ///     name: Ident,
939 ///     bang_token: Token![!],
940 ///     paren_token: Paren,
941 ///     tts: TokenStream,
942 /// }
943 ///
944 /// impl Synom for Macro {
945 ///     named!(parse -> Self, do_parse!(
946 ///         name: syn!(Ident) >>
947 ///         bang_token: punct!(!) >>
948 ///         body: parens!(syn!(TokenStream)) >>
949 ///         (Macro {
950 ///             name,
951 ///             bang_token,
952 ///             paren_token: body.0,
953 ///             tts: body.1,
954 ///         })
955 ///     ));
956 /// }
957 /// #
958 /// # fn main() {}
959 /// ```
960 ///
961 /// *This macro is available if Syn is built with the `"parsing"` feature.*
962 #[macro_export]
963 macro_rules! do_parse {
964     ($i:expr, ( $($rest:expr),* )) => {
965         ::std::result::Result::Ok((( $($rest),* ), $i))
966     };
967 
968     ($i:expr, $e:ident >> $($rest:tt)*) => {
969         do_parse!($i, call!($e) >> $($rest)*)
970     };
971 
972     ($i:expr, $submac:ident!( $($args:tt)* ) >> $($rest:tt)*) => {
973         match $submac!($i, $($args)*) {
974             ::std::result::Result::Err(err) =>
975                 ::std::result::Result::Err(err),
976             ::std::result::Result::Ok((_, i)) =>
977                 do_parse!(i, $($rest)*),
978         }
979     };
980 
981     ($i:expr, $field:ident : $e:ident >> $($rest:tt)*) => {
982         do_parse!($i, $field: call!($e) >> $($rest)*)
983     };
984 
985     ($i:expr, $field:ident : $submac:ident!( $($args:tt)* ) >> $($rest:tt)*) => {
986         match $submac!($i, $($args)*) {
987             ::std::result::Result::Err(err) =>
988                 ::std::result::Result::Err(err),
989             ::std::result::Result::Ok((o, i)) => {
990                 let $field = o;
991                 do_parse!(i, $($rest)*)
992             },
993         }
994     };
995 
996     ($i:expr, mut $field:ident : $e:ident >> $($rest:tt)*) => {
997         do_parse!($i, mut $field: call!($e) >> $($rest)*)
998     };
999 
1000     ($i:expr, mut $field:ident : $submac:ident!( $($args:tt)* ) >> $($rest:tt)*) => {
1001         match $submac!($i, $($args)*) {
1002             ::std::result::Result::Err(err) =>
1003                 ::std::result::Result::Err(err),
1004             ::std::result::Result::Ok((o, i)) => {
1005                 let mut $field = o;
1006                 do_parse!(i, $($rest)*)
1007             },
1008         }
1009     };
1010 }
1011 
1012 /// Parse nothing and succeed only if the end of the enclosing block has been
1013 /// reached.
1014 ///
1015 /// The enclosing block may be the full input if we are parsing at the top
1016 /// level, or the surrounding parenthesis/bracket/brace if we are parsing within
1017 /// those.
1018 ///
1019 /// - **Syntax:** `input_end!()`
1020 /// - **Output:** `()`
1021 ///
1022 /// ```rust
1023 /// #[macro_use]
1024 /// extern crate syn;
1025 ///
1026 /// use syn::Expr;
1027 /// use syn::synom::Synom;
1028 ///
1029 /// /// Parses any Rust expression followed either by a semicolon or by the end
1030 /// /// of the input.
1031 /// ///
1032 /// /// For example `many0!(syn!(TerminatedExpr))` would successfully parse the
1033 /// /// following input into three expressions.
1034 /// ///
1035 /// ///     1 + 1; second.two(); third!()
1036 /// ///
1037 /// /// Similarly within a block, `braced!(many0!(syn!(TerminatedExpr)))` would
1038 /// /// successfully parse three expressions.
1039 /// ///
1040 /// ///     { 1 + 1; second.two(); third!() }
1041 /// struct TerminatedExpr {
1042 ///     expr: Expr,
1043 ///     semi_token: Option<Token![;]>,
1044 /// }
1045 ///
1046 /// impl Synom for TerminatedExpr {
1047 ///     named!(parse -> Self, do_parse!(
1048 ///         expr: syn!(Expr) >>
1049 ///         semi_token: alt!(
1050 ///             input_end!() => { |_| None }
1051 ///             |
1052 ///             punct!(;) => { Some }
1053 ///         ) >>
1054 ///         (TerminatedExpr {
1055 ///             expr,
1056 ///             semi_token,
1057 ///         })
1058 ///     ));
1059 /// }
1060 /// #
1061 /// # fn main() {}
1062 /// ```
1063 ///
1064 /// *This macro is available if Syn is built with the `"parsing"` feature.*
1065 #[macro_export]
1066 macro_rules! input_end {
1067     ($i:expr,) => {
1068         $crate::parsers::input_end($i)
1069     };
1070 }
1071 
1072 // Not a public API
1073 #[doc(hidden)]
input_end(input: Cursor) -> PResult<'static, ()>1074 pub fn input_end(input: Cursor) -> PResult<'static, ()> {
1075     if input.eof() {
1076         Ok(((), Cursor::empty()))
1077     } else {
1078         parse_error()
1079     }
1080 }
1081 
1082 /// Turn a failed parse into `None` and a successful parse into `Some`.
1083 ///
1084 /// A failed parse consumes none of the input.
1085 ///
1086 /// - **Syntax:** `option!(THING)`
1087 /// - **Output:** `Option<THING>`
1088 ///
1089 /// ```rust
1090 /// #[macro_use]
1091 /// extern crate syn;
1092 ///
1093 /// use syn::{Label, Block};
1094 /// use syn::synom::Synom;
1095 ///
1096 /// /// Parses a Rust loop. Equivalent to syn::ExprLoop.
1097 /// ///
1098 /// /// Examples:
1099 /// ///     loop { println!("y"); }
1100 /// ///     'x: loop { break 'x; }
1101 /// struct ExprLoop {
1102 ///     label: Option<Label>,
1103 ///     loop_token: Token![loop],
1104 ///     body: Block,
1105 /// }
1106 ///
1107 /// impl Synom for ExprLoop {
1108 ///     named!(parse -> Self, do_parse!(
1109 ///         // Loop may or may not have a label.
1110 ///         label: option!(syn!(Label)) >>
1111 ///         loop_token: keyword!(loop) >>
1112 ///         body: syn!(Block) >>
1113 ///         (ExprLoop {
1114 ///             label,
1115 ///             loop_token,
1116 ///             body,
1117 ///         })
1118 ///     ));
1119 /// }
1120 /// #
1121 /// # fn main() {}
1122 /// ```
1123 ///
1124 /// *This macro is available if Syn is built with the `"parsing"` feature.*
1125 #[macro_export]
1126 macro_rules! option {
1127     ($i:expr, $submac:ident!( $($args:tt)* )) => {
1128         match $submac!($i, $($args)*) {
1129             ::std::result::Result::Ok((o, i)) =>
1130                 ::std::result::Result::Ok((Some(o), i)),
1131             ::std::result::Result::Err(_) =>
1132                 ::std::result::Result::Ok((None, $i)),
1133         }
1134     };
1135 
1136     ($i:expr, $f:expr) => {
1137         option!($i, call!($f));
1138     };
1139 }
1140 
1141 /// Parses nothing and always succeeds.
1142 ///
1143 /// This can be useful as a fallthrough case in [`alt!`], as shown below. Also
1144 /// useful for parsing empty delimiters using [`parens!`] or [`brackets!`] or
1145 /// [`braces!`] by parsing for example `braces!(epsilon!())` for an empty `{}`.
1146 ///
1147 /// [`alt!`]: macro.alt.html
1148 /// [`parens!`]: macro.parens.html
1149 /// [`brackets!`]: macro.brackets.html
1150 /// [`braces!`]: macro.braces.html
1151 ///
1152 /// - **Syntax:** `epsilon!()`
1153 /// - **Output:** `()`
1154 ///
1155 /// ```rust
1156 /// #[macro_use]
1157 /// extern crate syn;
1158 ///
1159 /// use syn::synom::Synom;
1160 ///
1161 /// enum Mutability {
1162 ///     Mutable(Token![mut]),
1163 ///     Immutable,
1164 /// }
1165 ///
1166 /// impl Synom for Mutability {
1167 ///     named!(parse -> Self, alt!(
1168 ///         keyword!(mut) => { Mutability::Mutable }
1169 ///         |
1170 ///         epsilon!() => { |_| Mutability::Immutable }
1171 ///     ));
1172 /// }
1173 /// #
1174 /// # fn main() {}
1175 /// ```
1176 ///
1177 /// *This macro is available if Syn is built with the `"parsing"` feature.*
1178 #[macro_export]
1179 macro_rules! epsilon {
1180     ($i:expr,) => {
1181         ::std::result::Result::Ok(((), $i))
1182     };
1183 }
1184 
1185 /// Run a parser, binding the result to a name, and then evaluating an
1186 /// expression.
1187 ///
1188 /// Discards the result of the expression and parser.
1189 ///
1190 /// - **Syntax:** `tap!(NAME : THING => EXPR)`
1191 /// - **Output:** `()`
1192 #[doc(hidden)]
1193 #[macro_export]
1194 macro_rules! tap {
1195     ($i:expr, $name:ident : $submac:ident!( $($args:tt)* ) => $e:expr) => {
1196         match $submac!($i, $($args)*) {
1197             ::std::result::Result::Ok((o, i)) => {
1198                 let $name = o;
1199                 $e;
1200                 ::std::result::Result::Ok(((), i))
1201             }
1202             ::std::result::Result::Err(err) =>
1203                 ::std::result::Result::Err(err),
1204         }
1205     };
1206 
1207     ($i:expr, $name:ident : $f:expr => $e:expr) => {
1208         tap!($i, $name: call!($f) => $e);
1209     };
1210 }
1211 
1212 /// Parse any type that implements the `Synom` trait.
1213 ///
1214 /// Any type implementing [`Synom`] can be used with this parser, whether the
1215 /// implementation is provided by Syn or is one that you write.
1216 ///
1217 /// [`Synom`]: synom/trait.Synom.html
1218 ///
1219 /// - **Syntax:** `syn!(TYPE)`
1220 /// - **Output:** `TYPE`
1221 ///
1222 /// ```rust
1223 /// #[macro_use]
1224 /// extern crate syn;
1225 ///
1226 /// use syn::{Ident, Item};
1227 /// use syn::token::Brace;
1228 /// use syn::synom::Synom;
1229 ///
1230 /// /// Parses a module containing zero or more Rust items.
1231 /// ///
1232 /// /// Example: `mod m { type Result<T> = ::std::result::Result<T, MyError>; }`
1233 /// struct SimpleMod {
1234 ///     mod_token: Token![mod],
1235 ///     name: Ident,
1236 ///     brace_token: Brace,
1237 ///     items: Vec<Item>,
1238 /// }
1239 ///
1240 /// impl Synom for SimpleMod {
1241 ///     named!(parse -> Self, do_parse!(
1242 ///         mod_token: keyword!(mod) >>
1243 ///         name: syn!(Ident) >>
1244 ///         body: braces!(many0!(syn!(Item))) >>
1245 ///         (SimpleMod {
1246 ///             mod_token,
1247 ///             name,
1248 ///             brace_token: body.0,
1249 ///             items: body.1,
1250 ///         })
1251 ///     ));
1252 /// }
1253 /// #
1254 /// # fn main() {}
1255 /// ```
1256 ///
1257 /// *This macro is available if Syn is built with the `"parsing"` feature.*
1258 #[macro_export]
1259 macro_rules! syn {
1260     ($i:expr, $t:ty) => {
1261         <$t as $crate::synom::Synom>::parse($i)
1262     };
1263 }
1264 
1265 /// Parse inside of `(` `)` parentheses.
1266 ///
1267 /// This macro parses a set of balanced parentheses and invokes a sub-parser on
1268 /// the content inside. The sub-parser is required to consume all tokens within
1269 /// the parentheses in order for this parser to return successfully.
1270 ///
1271 /// - **Syntax:** `parens!(CONTENT)`
1272 /// - **Output:** `(token::Paren, CONTENT)`
1273 ///
1274 /// ```rust
1275 /// #[macro_use]
1276 /// extern crate syn;
1277 ///
1278 /// use syn::Expr;
1279 /// use syn::token::Paren;
1280 ///
1281 /// /// Parses an expression inside of parentheses.
1282 /// ///
1283 /// /// Example: `(1 + 1)`
1284 /// named!(expr_paren -> (Paren, Expr), parens!(syn!(Expr)));
1285 /// #
1286 /// # fn main() {}
1287 /// ```
1288 ///
1289 /// *This macro is available if Syn is built with the `"parsing"` feature.*
1290 #[macro_export]
1291 macro_rules! parens {
1292     ($i:expr, $submac:ident!( $($args:tt)* )) => {
1293         $crate::token::Paren::parse($i, |i| $submac!(i, $($args)*))
1294     };
1295 
1296     ($i:expr, $f:expr) => {
1297         parens!($i, call!($f));
1298     };
1299 }
1300 
1301 /// Parse inside of `[` `]` square brackets.
1302 ///
1303 /// This macro parses a set of balanced brackets and invokes a sub-parser on the
1304 /// content inside. The sub-parser is required to consume all tokens within the
1305 /// brackets in order for this parser to return successfully.
1306 ///
1307 /// - **Syntax:** `brackets!(CONTENT)`
1308 /// - **Output:** `(token::Bracket, CONTENT)`
1309 ///
1310 /// ```rust
1311 /// #[macro_use]
1312 /// extern crate syn;
1313 ///
1314 /// use syn::Expr;
1315 /// use syn::token::Bracket;
1316 ///
1317 /// /// Parses an expression inside of brackets.
1318 /// ///
1319 /// /// Example: `[1 + 1]`
1320 /// named!(expr_paren -> (Bracket, Expr), brackets!(syn!(Expr)));
1321 /// #
1322 /// # fn main() {}
1323 /// ```
1324 ///
1325 /// *This macro is available if Syn is built with the `"parsing"` feature.*
1326 #[macro_export]
1327 macro_rules! brackets {
1328     ($i:expr, $submac:ident!( $($args:tt)* )) => {
1329         $crate::token::Bracket::parse($i, |i| $submac!(i, $($args)*))
1330     };
1331 
1332     ($i:expr, $f:expr) => {
1333         brackets!($i, call!($f));
1334     };
1335 }
1336 
1337 /// Parse inside of `{` `}` curly braces.
1338 ///
1339 /// This macro parses a set of balanced braces and invokes a sub-parser on the
1340 /// content inside. The sub-parser is required to consume all tokens within the
1341 /// braces in order for this parser to return successfully.
1342 ///
1343 /// - **Syntax:** `braces!(CONTENT)`
1344 /// - **Output:** `(token::Brace, CONTENT)`
1345 ///
1346 /// ```rust
1347 /// #[macro_use]
1348 /// extern crate syn;
1349 ///
1350 /// use syn::Expr;
1351 /// use syn::token::Brace;
1352 ///
1353 /// /// Parses an expression inside of braces.
1354 /// ///
1355 /// /// Example: `{1 + 1}`
1356 /// named!(expr_paren -> (Brace, Expr), braces!(syn!(Expr)));
1357 /// #
1358 /// # fn main() {}
1359 /// ```
1360 ///
1361 /// *This macro is available if Syn is built with the `"parsing"` feature.*
1362 #[macro_export]
1363 macro_rules! braces {
1364     ($i:expr, $submac:ident!( $($args:tt)* )) => {
1365         $crate::token::Brace::parse($i, |i| $submac!(i, $($args)*))
1366     };
1367 
1368     ($i:expr, $f:expr) => {
1369         braces!($i, call!($f));
1370     };
1371 }
1372 
1373 // Not public API.
1374 #[doc(hidden)]
1375 #[macro_export]
1376 macro_rules! grouped {
1377     ($i:expr, $submac:ident!( $($args:tt)* )) => {
1378         $crate::token::Group::parse($i, |i| $submac!(i, $($args)*))
1379     };
1380 
1381     ($i:expr, $f:expr) => {
1382         grouped!($i, call!($f));
1383     };
1384 }
1385