start converting macros combinators to functions

This commit is contained in:
Geoffroy Couprie 2019-03-06 18:20:02 +01:00
parent 4257253914
commit d2d97aa78c
8 changed files with 293 additions and 219 deletions

View File

@ -18,6 +18,7 @@ include = [
".travis.yml",
"Cargo.toml",
"src/*.rs",
"src/*/*.rs",
"tests/*.rs",
"build.rs"
]

View File

@ -20,27 +20,7 @@ use traits::{need_more, AtEof};
/// ```
#[macro_export(local_inner_macros)]
macro_rules! one_of (
($i:expr, $inp: expr) => (
{
use $crate::lib::std::result::Result::*;
use $crate::lib::std::option::Option::*;
use $crate::{Err,Needed};
use $crate::Slice;
use $crate::AsChar;
use $crate::FindToken;
use $crate::InputIter;
match ($i).iter_elements().next().map(|c| {
(c, $inp.find_token(c))
}) {
None => $crate::need_more($i, Needed::Size(1)),
Some((_, false)) => Err(Err::Error(error_position!($i, $crate::ErrorKind::OneOf::<u32>))),
//the unwrap should be safe here
Some((c, true)) => Ok(( $i.slice(c.len()..), $i.iter_elements().next().unwrap().as_char() ))
}
}
);
($i:expr, $inp: expr) => ( $crate::one_ofc($i, $inp) );
);
/// matches anything but the provided characters
@ -59,27 +39,7 @@ macro_rules! one_of (
/// ```
#[macro_export(local_inner_macros)]
macro_rules! none_of (
($i:expr, $inp: expr) => (
{
use $crate::lib::std::result::Result::*;
use $crate::lib::std::option::Option::*;
use $crate::{Err,Needed};
use $crate::Slice;
use $crate::AsChar;
use $crate::FindToken;
use $crate::InputIter;
match ($i).iter_elements().next().map(|c| {
(c, !$inp.find_token(c))
}) {
None => $crate::need_more($i, Needed::Size(1)),
Some((_, false)) => Err(Err::Error(error_position!($i, $crate::ErrorKind::NoneOf::<u32>))),
//the unwrap should be safe here
Some((c, true)) => Ok(( $i.slice(c.len()..), $i.iter_elements().next().unwrap().as_char() ))
}
}
);
($i:expr, $inp: expr) => ( $crate::none_ofc($i, $inp) );
);
/// matches one character: `char!(char) => &[u8] -> IResult<&[u8], char>
@ -97,30 +57,7 @@ macro_rules! none_of (
/// ```
#[macro_export(local_inner_macros)]
macro_rules! char (
($i:expr, $c: expr) => (
{
use $crate::lib::std::result::Result::*;
use $crate::lib::std::option::Option::*;
use $crate::{Err,Needed};
use $crate::Slice;
use $crate::AsChar;
use $crate::InputIter;
match ($i).iter_elements().next().map(|c| {
let b = c.as_char() == $c;
b
}) {
None => $crate::need_more($i, Needed::Size(1)),
Some(false) => {
let e: $crate::ErrorKind<u32> = $crate::ErrorKind::Char;
Err(Err::Error($crate::Context::Code($i, e)))
},
//the unwrap should be safe here
Some(true) => Ok(( $i.slice($c.len()..), $i.iter_elements().next().unwrap().as_char() ))
}
}
);
($i:expr, $c: expr) => ( $crate::charc($i, $c) );
);
named!(#[doc="Matches a newline character '\\n'"], pub newline<char>, char!('\n'));

84
src/character/mod.rs Normal file
View File

@ -0,0 +1,84 @@
#[macro_use]
mod macros;
pub use self::macros::anychar;
use internal::{Err,IResult,Needed};
use util::ErrorKind;
use traits::{AtEof,Slice,AsChar,InputIter,InputLength,FindToken,need_more};
use crate::Context;
use std::ops::RangeFrom;
pub fn char<I>(c: char) -> impl Fn(I) -> IResult<I, char>
where I: Slice<RangeFrom<usize>>+InputIter+AtEof,
<I as InputIter>::Item: AsChar {
move |i:I| {
match (i).iter_elements().next().map(|t| {
let b = t.as_char() == c;
(&c, b)
}) {
None => need_more(i, Needed::Size(1)),
Some((_, false)) => {
let e: ErrorKind<u32> = ErrorKind::Char;
Err(Err::Error(Context::Code(i, e)))
},
Some((c, true)) => Ok(( i.slice(c.len()..), c.as_char() ))
}
}
}
pub fn charc<I>(input: I, c: char) -> IResult<I, char>
where I: Slice<RangeFrom<usize>>+InputIter+AtEof,
<I as InputIter>::Item: AsChar {
char(c)(input)
}
pub fn one_of<I,T>(list: T) -> impl Fn(I) -> IResult<I, char>
where I: Slice<RangeFrom<usize>>+InputIter+AtEof,
<I as InputIter>::Item: AsChar+Copy,
T: FindToken<<I as InputIter>::Item> {
move |i:I| {
match (i).iter_elements().next().map(|c| {
(c, list.find_token(c))
}) {
None => need_more(i, Needed::Size(1)),
Some((_, false)) => Err(Err::Error(error_position!(i, ErrorKind::OneOf::<u32>))),
Some((c, true)) => Ok(( i.slice(c.len()..), c.as_char() ))
}
}
}
pub fn one_ofc<I,T>(input: I, list: T) -> IResult<I, char>
where I: Slice<RangeFrom<usize>>+InputIter+AtEof,
<I as InputIter>::Item: AsChar+Copy,
T: FindToken<<I as InputIter>::Item> {
one_of(list)(input)
}
pub fn none_of<I,T>(list: T) -> impl Fn(I) -> IResult<I, char>
where I: Slice<RangeFrom<usize>>+InputIter+AtEof,
<I as InputIter>::Item: AsChar+Copy,
T: FindToken<<I as InputIter>::Item> {
move |i:I| {
match (i).iter_elements().next().map(|c| {
(c, !list.find_token(c))
}) {
None => need_more(i, Needed::Size(1)),
Some((_, false)) => Err(Err::Error(error_position!(i, ErrorKind::NoneOf::<u32>))),
Some((c, true)) => Ok(( i.slice(c.len()..), c.as_char() ))
}
}
}
pub fn none_ofc<I,T>(input: I, list: T) -> IResult<I, char>
where I: Slice<RangeFrom<usize>>+InputIter+AtEof,
<I as InputIter>::Item: AsChar+Copy,
T: FindToken<<I as InputIter>::Item> {
none_of(list)(input)
}

View File

@ -241,48 +241,10 @@ macro_rules! separated_nonempty_list_complete {
#[macro_export(local_inner_macros)]
macro_rules! many0(
($i:expr, $submac:ident!( $($args:tt)* )) => (
{
use $crate::lib::std::result::Result::*;
use $crate::{Err,AtEof};
let ret;
let mut res = $crate::lib::std::vec::Vec::new();
let mut input = $i.clone();
loop {
let input_ = input.clone();
match $submac!(input_, $($args)*) {
Ok((i, o)) => {
// loop trip must always consume (otherwise infinite loops)
if i == input {
if i.at_eof() {
ret = Ok((input, res));
} else {
ret = Err(Err::Error(error_position!(input, $crate::ErrorKind::Many0)));
}
break;
}
res.push(o);
input = i;
},
Err(Err::Error(_)) => {
ret = Ok((input, res));
break;
},
Err(e) => {
ret = Err(e);
break;
},
}
}
ret
}
many0!($i, |i| $submac!(i, $($args)*))
);
($i:expr, $f:expr) => (
many0!($i, call!($f));
$crate::many0c($i, $f)
);
);
@ -317,55 +279,10 @@ macro_rules! many0(
#[macro_export(local_inner_macros)]
macro_rules! many1(
($i:expr, $submac:ident!( $($args:tt)* )) => (
{
use $crate::lib::std::result::Result::*;
use $crate::Err;
use $crate::InputLength;
let i_ = $i.clone();
match $submac!(i_, $($args)*) {
Err(Err::Error(_)) => Err(Err::Error(
error_position!(i_, $crate::ErrorKind::Many1)
)),
Err(Err::Failure(_)) => Err(Err::Failure(
error_position!(i_, $crate::ErrorKind::Many1)
)),
Err(i) => Err(i),
Ok((i1,o1)) => {
let mut res = $crate::lib::std::vec::Vec::with_capacity(4);
res.push(o1);
let mut input = i1;
let mut error = $crate::lib::std::option::Option::None;
loop {
let input_ = input.clone();
match $submac!(input_, $($args)*) {
Err(Err::Error(_)) => {
break;
},
Err(e) => {
error = $crate::lib::std::option::Option::Some(e);
break;
},
Ok((i, o)) => {
if i.input_len() == input.input_len() {
break;
}
res.push(o);
input = i;
}
}
}
match error {
$crate::lib::std::option::Option::Some(e) => Err(e),
$crate::lib::std::option::Option::None => Ok((input, res))
}
}
}
}
many1!($i, |i| $submac!(i, $($args)*))
);
($i:expr, $f:expr) => (
many1!($i, call!($f));
$crate::many1c($i, $f)
);
);
@ -1401,7 +1318,7 @@ mod tests {
#[test]
#[cfg(feature = "alloc")]
fn many1() {
named!(multi<&[u8],Vec<&[u8]> >, many1!(tag!("abcd")));
named!(multi<&[u8],Vec<&[u8]> >, many1!(dbg_dmp!(tag!("abcd"))));
let a = &b"abcdef"[..];
let b = &b"abcdabcdefgh"[..];

113
src/multi/mod.rs Normal file
View File

@ -0,0 +1,113 @@
#[macro_use]
mod macros;
use internal::{Err,IResult};
use util::ErrorKind;
use traits::{AtEof,InputLength};
pub fn many0c<I: Clone+InputLength+AtEof, O, F>(mut input: I, mut f: F) -> IResult<I, Vec<O>>
where F: FnMut(I) -> IResult<I, O> {
let mut acc = Vec::with_capacity(4);
loop {
let input_ = input.clone();
match f(input_) {
Err(Err::Error(_)) => return Ok((input, acc)),
Err(Err::Failure(e)) => return Err(Err::Failure(e)),
Err(Err::Incomplete(n)) => {
if input.at_eof() {
return Ok((input, acc));
} else {
return Err(Err::Incomplete(n));
}
}
Ok((i, o)) => {
if input.input_len() == i.input_len() {
return Err(Err::Error(error_position!(i, ErrorKind::Many0)))
}
input = i;
acc.push(o);
}
}
}
}
use std::fmt::Debug;
pub fn many1c<I: Clone+Copy+AtEof+InputLength+Debug, O:Debug, F>(input: I, f: F) -> IResult<I, Vec<O>>
where F: Fn(I) -> IResult<I, O> {
let input_ = input.clone();
match f(input_) {
Err(_) => {
return Err(Err::Error(error_position!(input, ErrorKind::Many1)))
},
Ok((i2, o)) => {
let mut acc = Vec::with_capacity(4);
acc.push(o);
let mut input = i2;
loop {
let input_ = input.clone();
match f(input_) {
Err(Err::Error(_)) => return Ok((input, acc)),
Err(Err::Failure(e)) => return Err(Err::Failure(e)),
Err(Err::Incomplete(n)) => {
if input.at_eof() {
return Ok((input, acc));
} else {
return Err(Err::Incomplete(n));
}
}
Ok((i, o)) => {
if input.input_len() == i.input_len() {
return Err(Err::Error(error_position!(i, ErrorKind::Many1)))
}
input = i;
acc.push(o);
}
}
}
}
}
}
pub fn separated_list<I: Clone+InputLength, O, O2, F, G>(input: I, mut sep: G, mut f: F) -> IResult<I, Vec<O>>
where F: FnMut(I) -> IResult<I, O>,
G: FnMut(I) -> IResult<I, O2> {
let mut acc = Vec::new();
let (input, o) = f(input)?;
acc.push(o);
let mut i = input;
loop {
if i.input_len() == 0 {
return Ok((i, acc));
}
let i_ = i.clone();
match sep(i_) {
Err(_) => return Ok((i, acc)),
Ok((i2, _)) => {
if i.input_len() == i2.input_len() {
return Err(Err::Error(error_position!(i, ErrorKind::Many0)))
}
let i2_ = i2.clone();
match f(i2_) {
Err(_) => return Ok((i, acc)),
Ok((i3, o)) => {
if i2.input_len() == i3.input_len() {
return Err(Err::Error(error_position!(i, ErrorKind::Many0)))
}
i = i3;
acc.push(o);
}
}
}
}
}
}

View File

@ -810,7 +810,7 @@ where
T: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
T: Clone + Offset,
T: InputIter + AtEof,
<T as InputIter>::Item: AsChar,
<T as InputIter>::Item: AsChar+Copy,
T: InputTakeAtPosition,
<T as InputTakeAtPosition>::Item: AsChar
{
@ -839,7 +839,7 @@ where
T: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
T: Clone + Offset,
T: InputIter + InputLength + ParseTo<f32> + AtEof,
<T as InputIter>::Item: AsChar,
<T as InputIter>::Item: AsChar+Copy,
T: InputTakeAtPosition,
<T as InputTakeAtPosition>::Item: AsChar
{
@ -854,7 +854,7 @@ where
T: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
T: Clone + Offset,
T: InputIter + InputLength + ParseTo<f32> + AtEof,
<T as InputIter>::Item: AsChar,
<T as InputIter>::Item: AsChar+Copy,
T: InputTakeAtPosition,
<T as InputTakeAtPosition>::Item: AsChar
{
@ -868,7 +868,7 @@ where
T: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
T: Clone + Offset,
T: InputIter + InputLength + ParseTo<f64> + AtEof,
<T as InputIter>::Item: AsChar,
<T as InputIter>::Item: AsChar+Copy,
T: InputTakeAtPosition,
<T as InputTakeAtPosition>::Item: AsChar
{
@ -883,7 +883,7 @@ where
T: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
T: Clone + Offset,
T: InputIter + InputLength + ParseTo<f64> + AtEof,
<T as InputIter>::Item: AsChar,
<T as InputIter>::Item: AsChar+Copy,
T: InputTakeAtPosition,
<T as InputTakeAtPosition>::Item: AsChar
{

View File

@ -93,21 +93,19 @@ macro_rules! tuple_parser (
#[macro_export(local_inner_macros)]
macro_rules! pair(
($i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
{
tuple!($i, $submac!($($args)*), $submac2!($($args2)*))
}
pair!($i, |i| $submac!(i, $($args)*), |i| $submac2!(i, $($args2)*))
);
($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => (
pair!($i, $submac!($($args)*), call!($g));
pair!($i, |i| $submac!(i, $($args)*), $g);
);
($i:expr, $f:expr, $submac:ident!( $($args:tt)* )) => (
pair!($i, call!($f), $submac!($($args)*));
pair!($i, $f, |i| $submac!(i, $($args)*));
);
($i:expr, $f:expr, $g:expr) => (
pair!($i, call!($f), call!($g));
$crate::pairc($i, $f, $g)
);
);
@ -115,21 +113,17 @@ macro_rules! pair(
/// separated_pair(X,sep,Y) returns (x,y)
#[macro_export(local_inner_macros)]
macro_rules! separated_pair(
($i:expr, $submac:ident!( $($args:tt)* ), $($rest:tt)+) => (
{
use $crate::lib::std::result::Result::*;
match tuple_parser!($i, (), $submac!($($args)*), $($rest)*) {
Err(e) => Err(e),
Ok((i1, (o1, _, o2))) => {
Ok((i1, (o1, o2)))
}
}
}
($i:expr, $submac:ident!( $($args:tt)* ), $($rest:tt)*) => (
separated_pair!($i, |i| $submac!(i, $($args)*), $($rest)*)
);
($i:expr, $f:expr, $($rest:tt)+) => (
separated_pair!($i, call!($f), $($rest)*);
($i:expr, $f:expr, $submac:ident!( $($args:tt)* ), $($rest:tt)*) => (
separated_pair!($i, $f, |i| $submac!(i, $($args)*), $($rest)*)
);
($i:expr, $f:expr, $g:expr, $submac:ident!( $($args:tt)* )) => (
separated_pair!($i, $f, $g, |i| $submac!(i, $($args)*))
);
($i:expr, $f:expr, $g:expr, $h:expr) => (
$crate::separated_pairc($i, $f, $g, $h)
);
);
@ -138,28 +132,19 @@ macro_rules! separated_pair(
#[macro_export(local_inner_macros)]
macro_rules! preceded(
($i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
{
use $crate::lib::std::result::Result::*;
match tuple!($i, $submac!($($args)*), $submac2!($($args2)*)) {
Err(e) => Err(e),
Ok((remaining, (_,o))) => {
Ok((remaining, o))
}
}
}
preceded!($i, |i| $submac!(i, $($args)*), |i| $submac2!(i, $($args2)*))
);
($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => (
preceded!($i, $submac!($($args)*), call!($g));
preceded!($i, |i| $submac!(i, $($args)*), $g);
);
($i:expr, $f:expr, $submac:ident!( $($args:tt)* )) => (
preceded!($i, call!($f), $submac!($($args)*));
preceded!($i, $f, |i| $submac!(i, $($args)*));
);
($i:expr, $f:expr, $g:expr) => (
preceded!($i, call!($f), call!($g));
$crate::precededc($i, $f, $g)
);
);
@ -168,28 +153,19 @@ macro_rules! preceded(
#[macro_export(local_inner_macros)]
macro_rules! terminated(
($i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
{
use $crate::lib::std::result::Result::*;
match tuple!($i, $submac!($($args)*), $submac2!($($args2)*)) {
Err(e) => Err(e),
Ok((remaining, (o,_))) => {
Ok((remaining, o))
}
}
}
terminated!($i, |i| $submac!(i, $($args)*), |i| $submac2!(i, $($args2)*))
);
($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => (
terminated!($i, $submac!($($args)*), call!($g));
terminated!($i, |i| $submac!(i, $($args)*), $g);
);
($i:expr, $f:expr, $submac:ident!( $($args:tt)* )) => (
terminated!($i, call!($f), $submac!($($args)*));
terminated!($i, $f, |i| $submac!(i, $($args)*));
);
($i:expr, $f:expr, $g:expr) => (
terminated!($i, call!($f), call!($g));
$crate::terminatedc($i, $f, $g)
);
);
@ -213,21 +189,17 @@ macro_rules! terminated(
/// ```
#[macro_export(local_inner_macros)]
macro_rules! delimited(
($i:expr, $submac:ident!( $($args:tt)* ), $($rest:tt)+) => (
{
use $crate::lib::std::result::Result::*;
match tuple_parser!($i, (), $submac!($($args)*), $($rest)*) {
Err(e) => Err(e),
Ok((i1, (_, o, _))) => {
Ok((i1, o))
}
}
}
($i:expr, $submac:ident!( $($args:tt)* ), $($rest:tt)*) => (
delimited!($i, |i| $submac!(i, $($args)*), $($rest)*)
);
($i:expr, $f:expr, $($rest:tt)+) => (
delimited!($i, call!($f), $($rest)*);
($i:expr, $f:expr, $submac:ident!( $($args:tt)* ), $($rest:tt)*) => (
delimited!($i, $f, |i| $submac!(i, $($args)*), $($rest)*)
);
($i:expr, $f:expr, $g:expr, $submac:ident!( $($args:tt)* )) => (
delimited!($i, $f, $g, |i| $submac!(i, $($args)*))
);
($i:expr, $f:expr, $g:expr, $h:expr) => (
$crate::delimitedc($i, $f, $g, $h)
);
);

50
src/sequence/mod.rs Normal file
View File

@ -0,0 +1,50 @@
#[macro_use]
mod macros;
use internal::IResult;
pub fn pairc<I, O1, O2, E, F, G>(input: I, first: F, second: G) -> IResult<I, (O1, O2), E>
where F: Fn(I) -> IResult<I, O1, E>,
G: Fn(I) -> IResult<I, O2, E> {
let (input, o1) = first(input)?;
second(input).map(|(i, o2)| (i, (o1, o2)))
}
pub fn precededc<I, O1, O2, E, F, G>(input: I, first: F, second: G) -> IResult<I, O2, E>
where F: Fn(I) -> IResult<I, O1, E>,
G: Fn(I) -> IResult<I, O2, E> {
let (input, _) = first(input)?;
second(input)
}
pub fn terminatedc<I, O1, O2, E, F, G>(input: I, first: F, second: G) -> IResult<I, O1, E>
where F: Fn(I) -> IResult<I, O1, E>,
G: Fn(I) -> IResult<I, O2, E> {
let (input, o1) = first(input)?;
second(input).map(|(i, _)| (i, o1))
}
pub fn separated_pairc<I, O1, O2, O3, E, F, G, H>(input: I, first: F, sep: G, second: H) -> IResult<I, (O1, O3), E>
where F: Fn(I) -> IResult<I, O1, E>,
G: Fn(I) -> IResult<I, O2, E>,
H: Fn(I) -> IResult<I, O3, E> {
let (input, o1) = first(input)?;
let (input, _) = sep(input)?;
second(input).map(|(i, o2)| (i, (o1, o2)))
}
// needs FnMut because fold_many0 in tests/reborrow_fold.rs will not compile otherwise
pub fn delimitedc<I, O1, O2, O3, E, F, G, H>(input: I, mut first: F, mut sep: G, mut second: H) -> IResult<I, O2, E>
where F: FnMut(I) -> IResult<I, O1, E>,
G: FnMut(I) -> IResult<I, O2, E>,
H: FnMut(I) -> IResult<I, O3, E> {
let (input, _) = first(input)?;
let (input, o2) = sep(input)?;
second(input).map(|(i, _)| (i, o2))
}