standalone_syn/
parsers.rs

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
9use buffer::Cursor;
10use parse_error;
11use 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]
66macro_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]
96macro_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]
145macro_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]
185macro_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)]
204pub 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]
234macro_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]
303macro_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]
386macro_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]
453macro_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)]
496pub 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]
595macro_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]
689macro_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]
722macro_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]
747macro_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]
756macro_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]
869macro_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]
963macro_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]
1066macro_rules! input_end {
1067    ($i:expr,) => {
1068        $crate::parsers::input_end($i)
1069    };
1070}
1071
1072// Not a public API
1073#[doc(hidden)]
1074pub 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]
1126macro_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]
1179macro_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]
1194macro_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]
1259macro_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]
1291macro_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]
1327macro_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]
1363macro_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]
1376macro_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}