Last active
August 24, 2016 23:26
-
-
Save ArtemGr/63a5957fb8b342e097f100d857e3dbf6 to your computer and use it in GitHub Desktop.
Nom tag that implements the /(?x) (.*?) (remainder)/ pattern.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// Implements the /(?x) (.*?) (remainder)/ pattern: | |
/// looks for remainder first, then returns a tuple with the prefix and the remainder. | |
/// Discussion: https://www.reddit.com/r/rust/comments/4yokxd/crash_course_into_nom_kind_of_question/ | |
macro_rules! take_until_parse_s ( | |
($i: expr, $submac: ident! ($($args:tt)*)) => ({ | |
let input = $i as &str; | |
let mut ret = IResult::Error (nom::Err::Position (nom::ErrorKind::Custom (0), input)); | |
for (pos, _) in $i.char_indices() { | |
match $submac! (&input[pos..], $($args)*) { | |
IResult::Done (i,o) => {ret = IResult::Done (i, (&input[0..pos], o)); break}, // Found the remainder! | |
IResult::Error(_) => continue, // Keep looking. | |
IResult::Incomplete(_) => continue}} // Keep looking. | |
if !ret.is_done() { | |
// Last chance. See if subparser accepts an empty string. | |
if let IResult::Done (i,o) = $submac! ("", $($args)*) { | |
ret = IResult::Done (i, (input, o))}} // Empty remainder was accepted. | |
ret}); | |
($i: expr, $f: expr) => (take_until_parse_s! ($i, call! ($f)););); | |
/// `$starts` is an optional `Pattern` used to optimize the `$submac` search. | |
/// For example, with jetscii: `take_until_find_parse_s! ("foo bar", ascii_chars! ('b'), tag_s! ("bar"))`. | |
macro_rules! take_until_find_parse_s ( | |
($i: expr, $starts: expr, $submac: ident! ($($args:tt)*)) => ({ | |
let input = $i as &str; | |
let mut ret = IResult::Error (nom::Err::Position (nom::ErrorKind::Custom (0), input)); | |
for (pos, _) in $i.match_indices ($starts) { | |
match $submac! (&input[pos..], $($args)*) { | |
IResult::Done (i,o) => {ret = IResult::Done (i, (&input[0..pos], o)); break}, // Found the remainder! | |
IResult::Error(_) => continue, // Keep looking. | |
IResult::Incomplete(_) => continue}} // Keep looking. | |
ret}); | |
($i: expr, $starts: expr, $f: expr) => (take_until_find_parse_s! ($i, $starts, call! ($f)););); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment