2018-01-07 12:46:10 -06:00
|
|
|
use super::*;
|
|
|
|
|
2018-01-08 12:57:19 -06:00
|
|
|
pub(super) fn mod_items(p: &mut Parser) {
|
|
|
|
many(p, |p| {
|
|
|
|
skip_to_first(
|
|
|
|
p, item_first, mod_item,
|
|
|
|
"expected item",
|
|
|
|
)
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
fn item_first(p: &Parser) -> bool {
|
2018-01-07 12:46:10 -06:00
|
|
|
match p.current() {
|
|
|
|
STRUCT_KW | FN_KW => true,
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-08 12:57:19 -06:00
|
|
|
fn mod_item(p: &mut Parser) {
|
|
|
|
if item(p) {
|
|
|
|
if p.current() == SEMI {
|
|
|
|
node(p, ERROR, |p| {
|
|
|
|
p.error()
|
|
|
|
.message("expected item, found `;`\n\
|
|
|
|
consider removing this semicolon")
|
|
|
|
.emit();
|
|
|
|
p.bump();
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn item(p: &mut Parser) -> bool {
|
2018-01-07 12:46:10 -06:00
|
|
|
attributes::outer_attributes(p);
|
|
|
|
visibility(p);
|
2018-01-08 13:20:58 -06:00
|
|
|
// node_if(p, USE_KW, USE_ITEM, use_item)
|
|
|
|
// || extern crate_fn
|
|
|
|
// || node_if(p, STATIC_KW, STATIC_ITEM, static_item)
|
|
|
|
// || node_if(p, CONST_KW, CONST_ITEM, const_item) or const FN!
|
|
|
|
// || unsafe trait, impl
|
|
|
|
// || node_if(p, FN_KW, FN_ITEM, fn_item)
|
|
|
|
// || node_if(p, MOD_KW, MOD_ITEM, mod_item)
|
|
|
|
// || node_if(p, TYPE_KW, TYPE_ITEM, type_item)
|
2018-01-07 12:46:10 -06:00
|
|
|
node_if(p, STRUCT_KW, STRUCT_ITEM, struct_item)
|
2018-01-08 12:57:19 -06:00
|
|
|
|| node_if(p, FN_KW, FN_ITEM, fn_item)
|
2018-01-07 12:46:10 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
fn struct_item(p: &mut Parser) {
|
|
|
|
p.expect(IDENT)
|
|
|
|
&& p.curly_block(|p| comma_list(p, EOF, struct_field));
|
|
|
|
}
|
|
|
|
|
|
|
|
fn struct_field(p: &mut Parser) -> bool {
|
|
|
|
node_if(p, IDENT, STRUCT_FIELD, |p| {
|
|
|
|
p.expect(COLON) && p.expect(IDENT);
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
fn fn_item(p: &mut Parser) {
|
|
|
|
p.expect(IDENT) && p.expect(L_PAREN) && p.expect(R_PAREN)
|
|
|
|
&& p.curly_block(|p| ());
|
|
|
|
}
|
|
|
|
|
|
|
|
|