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