blob: 5086c3d2d38e09c369173ffff91924f2faa8cf90 [file] [log] [blame]
David Tolnay86eca752016-09-04 11:26:41 -07001#![cfg(feature = "parsing")]
2
David Tolnayde206222016-09-30 11:47:01 -07003use nom::{IResult, multispace};
David Tolnay10413f02016-09-30 09:12:02 -07004use unicode_xid::UnicodeXID;
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 Tolnayaed77b02016-09-23 20:50:31 -070013 for (i, ch) in input.char_indices() {
David Tolnay13e5da42016-09-04 16:18:34 -070014 if !ch.is_whitespace() {
15 return if input[i..].starts_with(token) {
David Tolnay10413f02016-09-30 09:12:02 -070016 IResult::Done(&input[i + token.len()..], token)
David Tolnay13e5da42016-09-04 16:18:34 -070017 } else {
David Tolnayb5a7b142016-09-13 22:46:39 -070018 IResult::Error
David Tolnay13e5da42016-09-04 16:18:34 -070019 };
20 }
21 }
David Tolnayb5a7b142016-09-13 22:46:39 -070022 IResult::Error
David Tolnay13e5da42016-09-04 16:18:34 -070023}
24
David Tolnay10413f02016-09-30 09:12:02 -070025macro_rules! keyword {
26 ($i:expr, $keyword:expr) => {
27 $crate::helper::keyword($i, $keyword)
28 };
29}
30
31pub fn keyword<'a>(input: &'a str, token: &'static str) -> IResult<&'a str, &'a str> {
32 match punct(input, token) {
33 IResult::Done(rest, _) => {
34 match word_break(rest) {
35 IResult::Done(_, _) => IResult::Done(rest, token),
36 IResult::Error => IResult::Error,
37 }
38 }
39 IResult::Error => IResult::Error,
40 }
41}
42
David Tolnay590cdfd2016-10-01 08:51:55 -070043pub fn word_break(input: &str) -> IResult<&str, ()> {
David Tolnay10413f02016-09-30 09:12:02 -070044 match input.chars().next() {
45 Some(ch) if UnicodeXID::is_xid_continue(ch) => {
46 IResult::Error
47 }
48 Some(_) | None => {
49 IResult::Done(input, ())
50 }
51 }
52}
53
David Tolnayb5a7b142016-09-13 22:46:39 -070054macro_rules! option {
55 ($i:expr, $submac:ident!( $($args:tt)* )) => {
David Tolnayf6ccb832016-09-04 15:00:56 -070056 match $submac!($i, $($args)*) {
David Tolnayfa0edf22016-09-23 22:58:24 -070057 $crate::nom::IResult::Done(i, o) => $crate::nom::IResult::Done(i, Some(o)),
58 $crate::nom::IResult::Error => $crate::nom::IResult::Done($i, None),
David Tolnayf6ccb832016-09-04 15:00:56 -070059 }
David Tolnayb5a7b142016-09-13 22:46:39 -070060 };
David Tolnayf6ccb832016-09-04 15:00:56 -070061
David Tolnayb5a7b142016-09-13 22:46:39 -070062 ($i:expr, $f:expr) => {
63 option!($i, call!($f));
64 };
65}
66
67macro_rules! opt_vec {
68 ($i:expr, $submac:ident!( $($args:tt)* )) => {
David Tolnayb79ee962016-09-04 09:39:20 -070069 match $submac!($i, $($args)*) {
David Tolnayfa0edf22016-09-23 22:58:24 -070070 $crate::nom::IResult::Done(i, o) => $crate::nom::IResult::Done(i, o),
71 $crate::nom::IResult::Error => $crate::nom::IResult::Done($i, Vec::new()),
David Tolnayb79ee962016-09-04 09:39:20 -070072 }
David Tolnayb5a7b142016-09-13 22:46:39 -070073 };
74}
David Tolnayb79ee962016-09-04 09:39:20 -070075
76macro_rules! epsilon {
77 ($i:expr,) => {
David Tolnayfa0edf22016-09-23 22:58:24 -070078 $crate::nom::IResult::Done($i, ())
79 };
80}
81
82macro_rules! tap {
83 ($i:expr, $name:ident : $submac:ident!( $($args:tt)* ) => $e:expr) => {
84 match $submac!($i, $($args)*) {
85 $crate::nom::IResult::Done(i, o) => {
86 let $name = o;
87 $e;
88 $crate::nom::IResult::Done(i, ())
89 }
90 $crate::nom::IResult::Error => $crate::nom::IResult::Error,
91 }
92 };
93
94 ($i:expr, $name:ident : $f:expr => $e:expr) => {
95 tap!($i, $name: call!($f) => $e);
David Tolnayb79ee962016-09-04 09:39:20 -070096 };
97}
David Tolnayde206222016-09-30 11:47:01 -070098
99pub fn eat_spaces(input: &str) -> &str {
100 match multispace(input) {
101 IResult::Done(rest, _) => rest,
102 IResult::Error => input,
103 }
104}