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