blob: c1694ece9604770360526b2d93cb9bbe84537e1f [file] [log] [blame]
David Tolnay86eca752016-09-04 11:26:41 -07001#![cfg(feature = "parsing")]
2
David Tolnay14cbdeb2016-10-01 12:13:59 -07003use nom::IResult;
4use space::{whitespace, word_break};
David Tolnayb79ee962016-09-04 09:39:20 -07005
6macro_rules! punct {
7 ($i:expr, $punct:expr) => {
David Tolnay13e5da42016-09-04 16:18:34 -07008 $crate::helper::punct($i, $punct)
David Tolnayb79ee962016-09-04 09:39:20 -07009 };
10}
11
David Tolnay13e5da42016-09-04 16:18:34 -070012pub fn punct<'a>(input: &'a str, token: &'static str) -> IResult<&'a str, &'a str> {
David Tolnay14cbdeb2016-10-01 12:13:59 -070013 let input = match whitespace(input) {
14 IResult::Done(rest, _) => rest,
15 IResult::Error => input,
16 };
17 if input.starts_with(token) {
18 IResult::Done(&input[token.len()..], token)
19 } else {
20 IResult::Error
David Tolnay13e5da42016-09-04 16:18:34 -070021 }
David Tolnay13e5da42016-09-04 16:18:34 -070022}
23
David Tolnay10413f02016-09-30 09:12:02 -070024macro_rules! keyword {
25 ($i:expr, $keyword:expr) => {
26 $crate::helper::keyword($i, $keyword)
27 };
28}
29
30pub fn keyword<'a>(input: &'a str, token: &'static str) -> IResult<&'a str, &'a str> {
31 match punct(input, token) {
32 IResult::Done(rest, _) => {
33 match word_break(rest) {
34 IResult::Done(_, _) => IResult::Done(rest, token),
35 IResult::Error => IResult::Error,
36 }
37 }
38 IResult::Error => IResult::Error,
39 }
40}
41
David Tolnayb5a7b142016-09-13 22:46:39 -070042macro_rules! option {
43 ($i:expr, $submac:ident!( $($args:tt)* )) => {
David Tolnayf6ccb832016-09-04 15:00:56 -070044 match $submac!($i, $($args)*) {
David Tolnayfa0edf22016-09-23 22:58:24 -070045 $crate::nom::IResult::Done(i, o) => $crate::nom::IResult::Done(i, Some(o)),
46 $crate::nom::IResult::Error => $crate::nom::IResult::Done($i, None),
David Tolnayf6ccb832016-09-04 15:00:56 -070047 }
David Tolnayb5a7b142016-09-13 22:46:39 -070048 };
David Tolnayf6ccb832016-09-04 15:00:56 -070049
David Tolnayb5a7b142016-09-13 22:46:39 -070050 ($i:expr, $f:expr) => {
51 option!($i, call!($f));
52 };
53}
54
55macro_rules! opt_vec {
56 ($i:expr, $submac:ident!( $($args:tt)* )) => {
David Tolnayb79ee962016-09-04 09:39:20 -070057 match $submac!($i, $($args)*) {
David Tolnayfa0edf22016-09-23 22:58:24 -070058 $crate::nom::IResult::Done(i, o) => $crate::nom::IResult::Done(i, o),
59 $crate::nom::IResult::Error => $crate::nom::IResult::Done($i, Vec::new()),
David Tolnayb79ee962016-09-04 09:39:20 -070060 }
David Tolnayb5a7b142016-09-13 22:46:39 -070061 };
62}
David Tolnayb79ee962016-09-04 09:39:20 -070063
64macro_rules! epsilon {
65 ($i:expr,) => {
David Tolnayfa0edf22016-09-23 22:58:24 -070066 $crate::nom::IResult::Done($i, ())
67 };
68}
69
70macro_rules! tap {
71 ($i:expr, $name:ident : $submac:ident!( $($args:tt)* ) => $e:expr) => {
72 match $submac!($i, $($args)*) {
73 $crate::nom::IResult::Done(i, o) => {
74 let $name = o;
75 $e;
76 $crate::nom::IResult::Done(i, ())
77 }
78 $crate::nom::IResult::Error => $crate::nom::IResult::Error,
79 }
80 };
81
82 ($i:expr, $name:ident : $f:expr => $e:expr) => {
83 tap!($i, $name: call!($f) => $e);
David Tolnayb79ee962016-09-04 09:39:20 -070084 };
85}