Fix incomplete errors

This commit is contained in:
David Tolnay 2016-09-04 15:00:56 -07:00
parent e8796aaa28
commit f6ccb8370a
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82
7 changed files with 69 additions and 38 deletions

View File

@ -32,7 +32,7 @@ pub mod parsing {
use helper::escaped_string;
use nom::multispace;
named!(pub attribute<&str, Attribute>, alt!(
named!(pub attribute<&str, Attribute>, alt_complete!(
do_parse!(
punct!("#") >>
punct!("[") >>
@ -64,7 +64,7 @@ pub mod parsing {
tag_s!("\"")
));
named!(meta_item<&str, MetaItem>, alt!(
named!(meta_item<&str, MetaItem>, alt_complete!(
do_parse!(
ident: word >>
punct!("(") >>

View File

@ -42,23 +42,25 @@ pub enum Visibility {
#[cfg(feature = "parsing")]
pub mod parsing {
use super::*;
use nom::multispace;
fn ident_ch(ch: char) -> bool {
ch.is_alphanumeric() || ch == '_'
}
named!(pub word<&str, Ident>, preceded!(
opt!(call!(::nom::multispace)),
option!(multispace),
map!(take_while1_s!(ident_ch), Into::into)
));
named!(pub visibility<&str, Visibility>, preceded!(
opt!(call!(::nom::multispace)),
alt!(
terminated!(tag_s!("pub"), call!(::nom::multispace)) => { |_| Visibility::Public }
|
epsilon!() => { |_| Visibility::Inherited }
named!(pub visibility<&str, Visibility>, alt_complete!(
do_parse!(
punct!("pub") >>
multispace >>
(Visibility::Public)
)
|
epsilon!() => { |_| Visibility::Inherited }
));
}

View File

@ -71,7 +71,7 @@ pub mod parsing {
use nom::multispace;
named!(pub generics<&str, Generics>, do_parse!(
bracketed: alt!(
bracketed: alt_complete!(
do_parse!(
punct!("<") >>
lifetimes: separated_list!(punct!(","), lifetime_def) >>
@ -89,7 +89,7 @@ pub mod parsing {
punct!("where") >>
multispace >>
predicates: separated_nonempty_list!(punct!(","), where_predicate) >>
opt!(punct!(",")) >>
option!(punct!(",")) >>
(predicates)
)) >>
(Generics {
@ -132,7 +132,7 @@ pub mod parsing {
punct!(":"),
separated_nonempty_list!(punct!("+"), ty_param_bound)
)) >>
default: opt!(preceded!(
default: option!(preceded!(
punct!("="),
ty
)) >>
@ -143,7 +143,7 @@ pub mod parsing {
})
));
named!(pub ty_param_bound<&str, TyParamBound>, alt!(
named!(pub ty_param_bound<&str, TyParamBound>, alt_complete!(
tuple!(punct!("?"), punct!("Sized")) => { |_| TyParamBound::MaybeSized }
|
lifetime => { TyParamBound::Region }
@ -151,7 +151,7 @@ pub mod parsing {
poly_trait_ref => { TyParamBound::Trait }
));
named!(where_predicate<&str, WherePredicate>, alt!(
named!(where_predicate<&str, WherePredicate>, alt_complete!(
do_parse!(
ident: lifetime >>
punct!(":") >>

View File

@ -4,16 +4,29 @@ use nom::{self, IResult};
macro_rules! punct {
($i:expr, $punct:expr) => {
tuple!($i, opt!(call!(::nom::multispace)), tag_s!($punct))
complete!($i, preceded!(opt!(call!(::nom::multispace)), tag_s!($punct)))
};
}
macro_rules! option (
($i:expr, $submac:ident!( $($args:tt)* )) => ({
match $submac!($i, $($args)*) {
::nom::IResult::Done(i, o) => ::nom::IResult::Done(i, Some(o)),
::nom::IResult::Error(_) => ::nom::IResult::Done($i, None),
::nom::IResult::Incomplete(_) => ::nom::IResult::Done($i, None),
}
});
($i:expr, $f:expr) => (
option!($i, call!($f));
);
);
macro_rules! opt_vec (
($i:expr, $submac:ident!( $($args:tt)* )) => ({
match $submac!($i, $($args)*) {
::nom::IResult::Done(i, o) => ::nom::IResult::Done(i, o),
::nom::IResult::Error(_) => ::nom::IResult::Done($i, Vec::new()),
::nom::IResult::Incomplete(i) => ::nom::IResult::Incomplete(i)
::nom::IResult::Incomplete(_) => ::nom::IResult::Done($i, Vec::new()),
}
});
);

View File

@ -50,7 +50,7 @@ pub mod parsing {
named!(pub item<&str, Item>, do_parse!(
attrs: many0!(attribute) >>
vis: visibility >>
which: alt!(tag_s!("struct") | tag_s!("enum")) >>
which: alt_complete!(punct!("struct") | punct!("enum")) >>
multispace >>
ident: word >>
generics: generics >>
@ -71,11 +71,11 @@ pub mod parsing {
body: body,
})
) >>
opt!(multispace) >>
option!(multispace) >>
(item)
));
named!(struct_body<&str, (Style, Vec<Field>)>, alt!(
named!(struct_body<&str, (Style, Vec<Field>)>, alt_complete!(
struct_like_body => { |fields| (Style::Struct, fields) }
|
terminated!(tuple_like_body, punct!(";")) => { |fields| (Style::Tuple, fields) }
@ -86,7 +86,7 @@ pub mod parsing {
named!(enum_body<&str, Body>, do_parse!(
punct!("{") >>
variants: separated_list!(punct!(","), variant) >>
opt!(punct!(",")) >>
option!(punct!(",")) >>
punct!("}") >>
(Body::Enum(variants))
));
@ -94,7 +94,7 @@ pub mod parsing {
named!(variant<&str, Variant>, do_parse!(
attrs: many0!(attribute) >>
ident: word >>
body: alt!(
body: alt_complete!(
struct_like_body => { |fields| (Style::Struct, fields) }
|
tuple_like_body => { |fields| (Style::Tuple, fields) }
@ -112,7 +112,7 @@ pub mod parsing {
named!(struct_like_body<&str, Vec<Field> >, do_parse!(
punct!("{") >>
fields: separated_list!(punct!(","), struct_field) >>
opt!(punct!(",")) >>
option!(punct!(",")) >>
punct!("}") >>
(fields)
));
@ -120,7 +120,7 @@ pub mod parsing {
named!(tuple_like_body<&str, Vec<Field> >, do_parse!(
punct!("(") >>
fields: separated_list!(punct!(","), tuple_field) >>
opt!(punct!(",")) >>
option!(punct!(",")) >>
punct!(")") >>
(fields)
));

View File

@ -188,7 +188,7 @@ pub mod parsing {
use nom::{digit, multispace};
use std::str;
named!(pub ty<&str, Ty>, alt!(
named!(pub ty<&str, Ty>, alt_complete!(
ty_vec
|
ty_fixed_length_vec
@ -223,14 +223,14 @@ pub mod parsing {
punct!("[") >>
elem: ty >>
punct!(";") >>
opt!(multispace) >>
option!(multispace) >>
size: map_res!(digit, str::parse) >>
(Ty::FixedLengthVec(Box::new(elem), size))
));
named!(ty_ptr<&str, Ty>, do_parse!(
punct!("*") >>
mutability: alt!(
mutability: alt_complete!(
punct!("const") => { |_| Mutability::Immutable }
|
punct!("mut") => { |_| Mutability::Mutable }
@ -244,7 +244,7 @@ pub mod parsing {
named!(ty_rptr<&str, Ty>, do_parse!(
punct!("&") >>
life: opt!(lifetime) >>
life: option!(lifetime) >>
mutability: mutability >>
target: ty >>
(Ty::Rptr(life, Box::new(MutTy {
@ -264,7 +264,7 @@ pub mod parsing {
punct!("(") >>
inputs: separated_list!(punct!(","), fn_arg) >>
punct!(")") >>
output: opt!(preceded!(
output: option!(preceded!(
punct!("->"),
ty
)) >>
@ -294,7 +294,7 @@ pub mod parsing {
named!(ty_qpath<&str, Ty>, do_parse!(
punct!("<") >>
this: map!(ty, Box::new) >>
path: opt!(preceded!(
path: option!(preceded!(
tuple!(punct!("as"), multispace),
path
)) >>
@ -332,17 +332,18 @@ pub mod parsing {
(Ty::Paren(Box::new(elem)))
));
named!(mutability<&str, Mutability>, preceded!(
opt!(multispace),
alt!(
terminated!(tag_s!("mut"), multispace) => { |_| Mutability::Mutable }
|
epsilon!() => { |_| Mutability::Immutable }
named!(mutability<&str, Mutability>, alt_complete!(
do_parse!(
punct!("mut") >>
multispace >>
(Mutability::Mutable)
)
|
epsilon!() => { |_| Mutability::Immutable }
));
named!(path<&str, Path>, do_parse!(
global: opt!(punct!("::")) >>
global: option!(punct!("::")) >>
segments: separated_nonempty_list!(punct!("::"), path_segment) >>
(Path {
global: global.is_some(),
@ -350,7 +351,7 @@ pub mod parsing {
})
));
named!(path_segment<&str, PathSegment>, alt!(
named!(path_segment<&str, PathSegment>, alt_complete!(
do_parse!(
ident: word >>
punct!("<") >>
@ -402,7 +403,7 @@ pub mod parsing {
));
named!(fn_arg<&str, Arg>, do_parse!(
pat: opt!(terminated!(word, punct!(":"))) >>
pat: option!(terminated!(word, punct!(":"))) >>
ty: ty >>
(Arg {
pat: pat,

View File

@ -8,6 +8,21 @@ fn simple_ty(ident: &str) -> Ty {
})
}
#[test]
fn test_unit() {
let raw = "struct Unit;";
let expected = Item {
ident: "Unit".into(),
vis: Visibility::Inherited,
attrs: Vec::new(),
generics: Generics::default(),
body: Body::Struct(Style::Unit, Vec::new()),
};
assert_eq!(expected, parse(raw));
}
#[test]
fn test_struct() {
let raw = "