Switch from chain to do_parse
diff --git a/src/attr.rs b/src/attr.rs
index a5d7c7d..266bbb4 100644
--- a/src/attr.rs
+++ b/src/attr.rs
@@ -30,28 +30,28 @@
}
named!(pub attribute<&str, Attribute>, alt!(
- chain!(
- punct!("#") ~
- punct!("[") ~
- meta_item: meta_item ~
- punct!("]"),
- move || Attribute {
+ do_parse!(
+ punct!("#") >>
+ punct!("[") >>
+ meta_item: meta_item >>
+ punct!("]") >>
+ (Attribute {
value: meta_item,
is_sugared_doc: false,
- }
+ })
)
|
- chain!(
- punct!("///") ~
- space: multispace ~
- content: take_until_s!("\n"),
- move || Attribute {
+ do_parse!(
+ punct!("///") >>
+ space: multispace >>
+ content: take_until_s!("\n") >>
+ (Attribute {
value: MetaItem::NameValue(
"doc".to_string(),
format!("///{}{}", space, content),
),
is_sugared_doc: true,
- }
+ })
)
));
@@ -62,19 +62,19 @@
));
named!(meta_item<&str, MetaItem>, alt!(
- chain!(
- ident: word ~
- punct!("(") ~
- inner: separated_list!(punct!(","), meta_item) ~
- punct!(")"),
- move || MetaItem::List(ident, inner)
+ do_parse!(
+ ident: word >>
+ punct!("(") >>
+ inner: separated_list!(punct!(","), meta_item) >>
+ punct!(")") >>
+ (MetaItem::List(ident, inner))
)
|
- chain!(
- ident: word ~
- punct!("=") ~
- string: quoted,
- move || MetaItem::NameValue(ident, string)
+ do_parse!(
+ ident: word >>
+ punct!("=") >>
+ string: quoted >>
+ (MetaItem::NameValue(ident, string))
)
|
map!(word, MetaItem::Word)
diff --git a/src/do_parse.rs b/src/do_parse.rs
new file mode 100644
index 0000000..d56461c
--- /dev/null
+++ b/src/do_parse.rs
@@ -0,0 +1,101 @@
+// Copied from nom master:
+// https://github.com/Geal/nom/blob/a38188f333c29d00c32a3082bec5491d2eefa33f/src/sequence.rs#L591-L687
+// Will be released in nom 2.0.
+
+#[macro_export]
+macro_rules! do_parse (
+ ($i:expr, $($rest:tt)*) => (
+ {
+ do_parse_impl!($i, 0usize, $($rest)*)
+ }
+ );
+);
+
+/// Internal parser, do not use directly
+#[doc(hidden)]
+#[macro_export]
+macro_rules! do_parse_impl (
+
+ ($i:expr, $consumed:expr, ( $($rest:expr),* )) => (
+ ::nom::IResult::Done($i, ( $($rest),* ))
+ );
+
+ ($i:expr, $consumed:expr, $e:ident >> $($rest:tt)*) => (
+ do_parse_impl!($i, $consumed, call!($e) >> $($rest)*);
+ );
+ ($i:expr, $consumed:expr, $submac:ident!( $($args:tt)* ) >> $($rest:tt)*) => (
+ {
+ match $submac!($i, $($args)*) {
+ ::nom::IResult::Error(e) => ::nom::IResult::Error(e),
+ ::nom::IResult::Incomplete(::nom::Needed::Unknown) =>
+ ::nom::IResult::Incomplete(::nom::Needed::Unknown),
+ ::nom::IResult::Incomplete(::nom::Needed::Size(i)) =>
+ ::nom::IResult::Incomplete(::nom::Needed::Size($consumed + i)),
+ ::nom::IResult::Done(i,_) => {
+ do_parse_impl!(i,
+ $consumed + (::nom::InputLength::input_len(&($i)) -
+ ::nom::InputLength::input_len(&i)), $($rest)*)
+ },
+ }
+ }
+ );
+
+ ($i:expr, $consumed:expr, $field:ident : $e:ident >> $($rest:tt)*) => (
+ do_parse_impl!($i, $consumed, $field: call!($e) >> $($rest)*);
+ );
+
+ ($i:expr, $consumed:expr, $field:ident : $submac:ident!( $($args:tt)* ) >> $($rest:tt)*) => (
+ {
+ match $submac!($i, $($args)*) {
+ ::nom::IResult::Error(e) => ::nom::IResult::Error(e),
+ ::nom::IResult::Incomplete(::nom::Needed::Unknown) =>
+ ::nom::IResult::Incomplete(::nom::Needed::Unknown),
+ ::nom::IResult::Incomplete(::nom::Needed::Size(i)) =>
+ ::nom::IResult::Incomplete(::nom::Needed::Size($consumed + i)),
+ ::nom::IResult::Done(i,o) => {
+ let $field = o;
+ do_parse_impl!(i,
+ $consumed + (::nom::InputLength::input_len(&($i)) -
+ ::nom::InputLength::input_len(&i)), $($rest)*)
+ },
+ }
+ }
+ );
+
+ // ending the chain
+ ($i:expr, $consumed:expr, $e:ident >> ( $($rest:tt)* )) => (
+ do_parse_impl!($i, $consumed, call!($e) >> ( $($rest)* ));
+ );
+
+ ($i:expr, $consumed:expr, $submac:ident!( $($args:tt)* ) >> ( $($rest:tt)* )) => (
+ match $submac!($i, $($args)*) {
+ ::nom::IResult::Error(e) => ::nom::IResult::Error(e),
+ ::nom::IResult::Incomplete(::nom::Needed::Unknown) =>
+ ::nom::IResult::Incomplete(::nom::Needed::Unknown),
+ ::nom::IResult::Incomplete(::nom::Needed::Size(i)) =>
+ ::nom::IResult::Incomplete(::nom::Needed::Size($consumed + i)),
+ ::nom::IResult::Done(i,_) => {
+ ::nom::IResult::Done(i, ( $($rest)* ))
+ },
+ }
+ );
+
+ ($i:expr, $consumed:expr, $field:ident : $e:ident >> ( $($rest:tt)* )) => (
+ do_parse_impl!($i, $consumed, $field: call!($e) >> ( $($rest)* ) );
+ );
+
+ ($i:expr, $consumed:expr, $field:ident : $submac:ident!( $($args:tt)* ) >> ( $($rest:tt)* )) => (
+ match $submac!($i, $($args)*) {
+ ::nom::IResult::Error(e) => ::nom::IResult::Error(e),
+ ::nom::IResult::Incomplete(::nom::Needed::Unknown) =>
+ ::nom::IResult::Incomplete(::nom::Needed::Unknown),
+ ::nom::IResult::Incomplete(::nom::Needed::Size(i)) =>
+ ::nom::IResult::Incomplete(::nom::Needed::Size($consumed + i)),
+ ::nom::IResult::Done(i,o) => {
+ let $field = o;
+ ::nom::IResult::Done(i, ( $($rest)* ))
+ },
+ }
+ );
+
+);
diff --git a/src/generics.rs b/src/generics.rs
index 92a6a1d..425228d 100644
--- a/src/generics.rs
+++ b/src/generics.rs
@@ -67,33 +67,33 @@
pub bounds: Vec<Lifetime>,
}
-named!(pub generics<&str, Generics>, chain!(
+named!(pub generics<&str, Generics>, do_parse!(
bracketed: alt!(
- chain!(
- punct!("<") ~
- lifetimes: separated_list!(punct!(","), lifetime_def) ~
+ do_parse!(
+ punct!("<") >>
+ lifetimes: separated_list!(punct!(","), lifetime_def) >>
ty_params: opt_vec!(preceded!(
cond!(!lifetimes.is_empty(), punct!(",")),
separated_nonempty_list!(punct!(","), ty_param)
- )) ~
- punct!(">"),
- move || (lifetimes, ty_params)
+ )) >>
+ punct!(">") >>
+ (lifetimes, ty_params)
)
|
epsilon!() => { |_| (Vec::new(), Vec::new()) }
- ) ~
- where_clause: opt_vec!(chain!(
- punct!("where") ~
- multispace ~
- predicates: separated_nonempty_list!(punct!(","), where_predicate) ~
- punct!(",")? ~
- move || predicates
- )),
- move || Generics {
+ ) >>
+ where_clause: opt_vec!(do_parse!(
+ punct!("where") >>
+ multispace >>
+ predicates: separated_nonempty_list!(punct!(","), where_predicate) >>
+ opt!(punct!(",")) >>
+ (predicates)
+ )) >>
+ (Generics {
lifetimes: bracketed.0,
ty_params: bracketed.1,
where_clause: where_clause,
- }
+ })
));
named!(pub lifetime<&str, Lifetime>, preceded!(
@@ -101,41 +101,41 @@
map!(word, |ident| Lifetime { ident: ident })
));
-named!(pub lifetime_def<&str, LifetimeDef>, chain!(
- life: lifetime ~
+named!(pub lifetime_def<&str, LifetimeDef>, do_parse!(
+ life: lifetime >>
bounds: opt_vec!(preceded!(
punct!(":"),
separated_nonempty_list!(punct!(","), lifetime)
- )),
- move || LifetimeDef {
+ )) >>
+ (LifetimeDef {
lifetime: life,
bounds: bounds,
- }
+ })
));
-named!(pub bound_lifetimes<&str, Vec<LifetimeDef> >, opt_vec!(chain!(
- punct!("for") ~
- punct!("<") ~
- lifetimes: separated_list!(punct!(","), lifetime_def) ~
- punct!(">"),
- move || lifetimes
+named!(pub bound_lifetimes<&str, Vec<LifetimeDef> >, opt_vec!(do_parse!(
+ punct!("for") >>
+ punct!("<") >>
+ lifetimes: separated_list!(punct!(","), lifetime_def) >>
+ punct!(">") >>
+ (lifetimes)
)));
-named!(ty_param<&str, TyParam>, chain!(
- ident: word ~
+named!(ty_param<&str, TyParam>, do_parse!(
+ ident: word >>
bounds: opt_vec!(preceded!(
punct!(":"),
separated_nonempty_list!(punct!("+"), ty_param_bound)
- )) ~
+ )) >>
default: opt!(preceded!(
punct!("="),
ty
- )) ~
- move || TyParam {
+ )) >>
+ (TyParam {
ident: ident,
bounds: bounds,
default: default,
- }
+ })
));
named!(pub ty_param_bound<&str, TyParamBound>, alt!(
@@ -147,25 +147,25 @@
));
named!(where_predicate<&str, WherePredicate>, alt!(
- chain!(
- ident: lifetime ~
- punct!(":") ~
- bounds: separated_nonempty_list!(punct!("+"), lifetime),
- move || WherePredicate::RegionPredicate(WhereRegionPredicate {
+ do_parse!(
+ ident: lifetime >>
+ punct!(":") >>
+ bounds: separated_nonempty_list!(punct!("+"), lifetime) >>
+ (WherePredicate::RegionPredicate(WhereRegionPredicate {
lifetime: ident,
bounds: bounds,
- })
+ }))
)
|
- chain!(
- bound_lifetimes: bound_lifetimes ~
- bounded_ty: ty ~
- punct!(":") ~
- bounds: separated_nonempty_list!(punct!("+"), ty_param_bound),
- move || WherePredicate::BoundPredicate(WhereBoundPredicate {
+ do_parse!(
+ bound_lifetimes: bound_lifetimes >>
+ bounded_ty: ty >>
+ punct!(":") >>
+ bounds: separated_nonempty_list!(punct!("+"), ty_param_bound) >>
+ (WherePredicate::BoundPredicate(WhereBoundPredicate {
bound_lifetimes: bound_lifetimes,
bounded_ty: bounded_ty,
bounds: bounds,
- })
+ }))
)
));
diff --git a/src/item.rs b/src/item.rs
index cab2685..544b55f 100644
--- a/src/item.rs
+++ b/src/item.rs
@@ -44,13 +44,13 @@
pub ty: Ty,
}
-named!(pub item<&str, Item>, chain!(
- attrs: many0!(attribute) ~
- vis: visibility ~
- which: alt!(tag_s!("struct") | tag_s!("enum")) ~
- multispace ~
- ident: word ~
- generics: generics ~
+named!(pub item<&str, Item>, do_parse!(
+ attrs: many0!(attribute) >>
+ vis: visibility >>
+ which: alt!(tag_s!("struct") | tag_s!("enum")) >>
+ multispace >>
+ ident: word >>
+ generics: generics >>
item: switch!(value!(which),
"struct" => map!(struct_body, move |(style, fields)| Item {
ident: ident,
@@ -67,9 +67,9 @@
generics: generics,
body: body,
})
- ) ~
- multispace?,
- move || item
+ ) >>
+ opt!(multispace) >>
+ (item)
));
named!(struct_body<&str, (Style, Vec<Field>)>, alt!(
@@ -80,70 +80,70 @@
punct!(";") => { |_| (Style::Unit, Vec::new()) }
));
-named!(enum_body<&str, Body>, chain!(
- punct!("{") ~
- variants: separated_list!(punct!(","), variant) ~
- punct!(",")? ~
- punct!("}"),
- move || Body::Enum(variants)
+named!(enum_body<&str, Body>, do_parse!(
+ punct!("{") >>
+ variants: separated_list!(punct!(","), variant) >>
+ opt!(punct!(",")) >>
+ punct!("}") >>
+ (Body::Enum(variants))
));
-named!(variant<&str, Variant>, chain!(
- attrs: many0!(attribute) ~
- ident: word ~
+named!(variant<&str, Variant>, do_parse!(
+ attrs: many0!(attribute) >>
+ ident: word >>
body: alt!(
struct_like_body => { |fields| (Style::Struct, fields) }
|
tuple_like_body => { |fields| (Style::Tuple, fields) }
|
epsilon!() => { |_| (Style::Unit, Vec::new()) }
- ),
- move || Variant {
+ ) >>
+ (Variant {
ident: ident,
attrs: attrs,
style: body.0,
fields: body.1,
- }
+ })
));
-named!(struct_like_body<&str, Vec<Field> >, chain!(
- punct!("{") ~
- fields: separated_list!(punct!(","), struct_field) ~
- punct!(",")? ~
- punct!("}"),
- move || fields
+named!(struct_like_body<&str, Vec<Field> >, do_parse!(
+ punct!("{") >>
+ fields: separated_list!(punct!(","), struct_field) >>
+ opt!(punct!(",")) >>
+ punct!("}") >>
+ (fields)
));
-named!(tuple_like_body<&str, Vec<Field> >, chain!(
- punct!("(") ~
- fields: separated_list!(punct!(","), tuple_field) ~
- punct!(",")? ~
- punct!(")"),
- move || fields
+named!(tuple_like_body<&str, Vec<Field> >, do_parse!(
+ punct!("(") >>
+ fields: separated_list!(punct!(","), tuple_field) >>
+ opt!(punct!(",")) >>
+ punct!(")") >>
+ (fields)
));
-named!(struct_field<&str, Field>, chain!(
- attrs: many0!(attribute) ~
- vis: visibility ~
- ident: word ~
- punct!(":") ~
- ty: ty,
- move || Field {
+named!(struct_field<&str, Field>, do_parse!(
+ attrs: many0!(attribute) >>
+ vis: visibility >>
+ ident: word >>
+ punct!(":") >>
+ ty: ty >>
+ (Field {
ident: Some(ident),
vis: vis,
attrs: attrs,
ty: ty,
- }
+ })
));
-named!(tuple_field<&str, Field>, chain!(
- attrs: many0!(attribute) ~
- vis: visibility ~
- ty: ty,
- move || Field {
+named!(tuple_field<&str, Field>, do_parse!(
+ attrs: many0!(attribute) >>
+ vis: visibility >>
+ ty: ty >>
+ (Field {
ident: None,
vis: vis,
attrs: attrs,
ty: ty,
- }
+ })
));
diff --git a/src/lib.rs b/src/lib.rs
index de2418c..ebd3c8e 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -2,6 +2,9 @@
extern crate nom;
#[macro_use]
+mod do_parse;
+
+#[macro_use]
mod helper;
mod attr;
diff --git a/src/ty.rs b/src/ty.rs
index 4aa3199..7393719 100644
--- a/src/ty.rs
+++ b/src/ty.rs
@@ -193,56 +193,56 @@
punct!("]")
) => { |elem| Ty::Vec(Box::new(elem)) }
|
- chain!(
- punct!("[") ~
- elem: ty ~
- punct!(";") ~
- multispace? ~
- size: map_res!(digit, str::parse),
- move || Ty::FixedLengthVec(Box::new(elem), size)
+ do_parse!(
+ punct!("[") >>
+ elem: ty >>
+ punct!(";") >>
+ opt!(multispace) >>
+ size: map_res!(digit, str::parse) >>
+ (Ty::FixedLengthVec(Box::new(elem), size))
)
|
- chain!(
- punct!("*") ~
+ do_parse!(
+ punct!("*") >>
mutability: alt!(
punct!("const") => { |_| Mutability::Immutable }
|
punct!("mut") => { |_| Mutability::Mutable }
- ) ~
- target: ty,
- move || Ty::Ptr(Box::new(MutTy {
+ ) >>
+ target: ty >>
+ (Ty::Ptr(Box::new(MutTy {
ty: target,
mutability: mutability,
- }))
+ })))
)
|
- chain!(
- punct!("&") ~
- life: lifetime? ~
- mutability: mutability ~
- target: ty,
- move || Ty::Rptr(life, Box::new(MutTy {
+ do_parse!(
+ punct!("&") >>
+ life: opt!(lifetime) >>
+ mutability: mutability >>
+ target: ty >>
+ (Ty::Rptr(life, Box::new(MutTy {
ty: target,
mutability: mutability,
- }))
+ })))
)
|
- chain!(
- punct!("fn") ~
- multispace ~
+ do_parse!(
+ punct!("fn") >>
+ multispace >>
lifetimes: opt_vec!(delimited!(
punct!("<"),
separated_list!(punct!(","), lifetime_def),
punct!(">")
- )) ~
- punct!("(") ~
- inputs: separated_list!(punct!(","), fn_arg) ~
- punct!(")") ~
+ )) >>
+ punct!("(") >>
+ inputs: separated_list!(punct!(","), fn_arg) >>
+ punct!(")") >>
output: opt!(preceded!(
punct!("->"),
ty
- )),
- move || Ty::BareFn(Box::new(BareFnTy {
+ )) >>
+ (Ty::BareFn(Box::new(BareFnTy {
lifetimes: lifetimes,
decl: FnDecl {
inputs: inputs,
@@ -251,7 +251,7 @@
None => FunctionRetTy::Default,
},
},
- }))
+ })))
)
|
punct!("!") => { |_| Ty::Never }
@@ -264,17 +264,17 @@
|
path => { |p| Ty::Path(None, p) }
|
- chain!(
- punct!("<") ~
- this: map!(ty, Box::new) ~
+ do_parse!(
+ punct!("<") >>
+ this: map!(ty, Box::new) >>
path: opt!(preceded!(
tuple!(punct!("as"), multispace),
path
- )) ~
- punct!(">") ~
- punct!("::") ~
- rest: separated_nonempty_list!(punct!("::"), path_segment),
- move || {
+ )) >>
+ punct!(">") >>
+ punct!("::") >>
+ rest: separated_nonempty_list!(punct!("::"), path_segment) >>
+ ({
match path {
Some(mut path) => {
let pos = path.segments.len();
@@ -288,7 +288,7 @@
})
}
}
- }
+ })
)
|
preceded!(
@@ -312,33 +312,33 @@
)
));
-named!(path<&str, Path>, chain!(
- global: punct!("::")? ~
- segments: separated_nonempty_list!(punct!("::"), path_segment),
- move || Path {
+named!(path<&str, Path>, do_parse!(
+ global: opt!(punct!("::")) >>
+ segments: separated_nonempty_list!(punct!("::"), path_segment) >>
+ (Path {
global: global.is_some(),
segments: segments,
- }
+ })
));
named!(path_segment<&str, PathSegment>, alt!(
- chain!(
- ident: word ~
- punct!("<") ~
- lifetimes: separated_list!(punct!(","), lifetime) ~
+ do_parse!(
+ ident: word >>
+ punct!("<") >>
+ lifetimes: separated_list!(punct!(","), lifetime) >>
types: opt_vec!(preceded!(
cond!(!lifetimes.is_empty(), punct!(",")),
separated_nonempty_list!(
punct!(","),
terminated!(ty, not!(peek!(punct!("="))))
)
- )) ~
+ )) >>
bindings: opt_vec!(preceded!(
cond!(!lifetimes.is_empty() || !types.is_empty(), punct!(",")),
separated_nonempty_list!(punct!(","), type_binding)
- )) ~
- punct!(">"),
- move || PathSegment {
+ )) >>
+ punct!(">") >>
+ (PathSegment {
ident: ident,
parameters: PathParameters::AngleBracketed(
AngleBracketedParameterData {
@@ -347,36 +347,36 @@
bindings: bindings,
}
),
- }
+ })
)
|
map!(word, PathSegment::ident)
));
-named!(type_binding<&str, TypeBinding>, chain!(
- ident: word ~
- punct!("=") ~
- ty: ty,
- move || TypeBinding {
+named!(type_binding<&str, TypeBinding>, do_parse!(
+ ident: word >>
+ punct!("=") >>
+ ty: ty >>
+ (TypeBinding {
ident: ident,
ty: ty,
- }
+ })
));
-named!(pub poly_trait_ref<&str, PolyTraitRef>, chain!(
- bound_lifetimes: bound_lifetimes ~
- trait_ref: path,
- move || PolyTraitRef {
+named!(pub poly_trait_ref<&str, PolyTraitRef>, do_parse!(
+ bound_lifetimes: bound_lifetimes >>
+ trait_ref: path >>
+ (PolyTraitRef {
bound_lifetimes: bound_lifetimes,
trait_ref: trait_ref,
- }
+ })
));
-named!(fn_arg<&str, Arg>, chain!(
- pat: opt!(terminated!(word, punct!(":"))) ~
- ty: ty,
- move || Arg {
+named!(fn_arg<&str, Arg>, do_parse!(
+ pat: opt!(terminated!(word, punct!(":"))) >>
+ ty: ty >>
+ (Arg {
pat: pat,
ty: ty,
- }
+ })
));