G: item outer attributes

This commit is contained in:
Aleksey Kladov 2018-01-11 23:01:12 +03:00
parent 89699c4803
commit 9a8e9bc4c6
6 changed files with 57 additions and 9 deletions

View file

@ -1,22 +1,26 @@
use super::*; use super::*;
enum AttrKind {
Inner, Outer
}
pub(super) fn inner_attributes(p: &mut Parser) { pub(super) fn inner_attributes(p: &mut Parser) {
many(p, |p| attribute(p, true)) many(p, |p| attribute(p, AttrKind::Inner))
} }
pub(super) fn outer_attributes(_: &mut Parser) { pub(super) fn outer_attributes(p: &mut Parser) {
many(p, |p| attribute(p, AttrKind::Outer))
} }
fn attribute(p: &mut Parser, inner: bool) -> bool { fn attribute(p: &mut Parser, kind: AttrKind) -> bool {
fn attr_tail(p: &mut Parser) { fn attr_tail(p: &mut Parser) {
meta_item(p) && p.expect(R_BRACK); meta_item(p) && p.expect(R_BRACK);
} }
if inner { match kind {
node_if(p, [POUND, EXCL, L_BRACK], ATTR, attr_tail) AttrKind::Inner => node_if(p, [POUND, EXCL, L_BRACK], ATTR, attr_tail),
} else { AttrKind::Outer => node_if(p, [POUND, L_BRACK], ATTR, attr_tail),
node_if(p, [POUND, L_BRACK], ATTR, attr_tail)
} }
} }

View file

@ -12,7 +12,7 @@ pub(super) fn mod_contents(p: &mut Parser) {
fn item_first(p: &Parser) -> bool { fn item_first(p: &Parser) -> bool {
match p.current() { match p.current() {
STRUCT_KW | FN_KW | EXTERN_KW | MOD_KW | USE_KW => true, STRUCT_KW | FN_KW | EXTERN_KW | MOD_KW | USE_KW | POUND => true,
_ => false, _ => false,
} }
} }

View file

@ -41,7 +41,15 @@ fn node<F: FnOnce(&mut Parser)>(p: &mut Parser, node_kind: SyntaxKind, rest: F)
} }
fn many<F: Fn(&mut Parser) -> bool>(p: &mut Parser, f: F) { fn many<F: Fn(&mut Parser) -> bool>(p: &mut Parser, f: F) {
while f(p) { } loop {
let pos = p.pos();
if !f(p) {
return
}
if pos == p.pos() {
panic!("Infinite loop in parser")
}
}
} }
fn comma_list<F: Fn(&mut Parser) -> bool>(p: &mut Parser, end: SyntaxKind, f: F) { fn comma_list<F: Fn(&mut Parser) -> bool>(p: &mut Parser, end: SyntaxKind, f: F) {

View file

@ -44,6 +44,10 @@ impl<'t> Parser<'t> {
} }
} }
pub(crate) fn pos(&self) -> usize {
self.pos
}
pub(crate) fn into_events(self) -> Vec<Event> { pub(crate) fn into_events(self) -> Vec<Event> {
assert!(self.curly_limit.is_none()); assert!(self.curly_limit.is_none());
assert!(self.current() == EOF); assert!(self.current() == EOF);

View file

@ -0,0 +1,3 @@
#[cfg(test)]
#[ignore]
fn foo() {}

View file

@ -0,0 +1,29 @@
FILE@[0; 35)
ATTR@[0; 13)
POUND@[0; 1)
L_BRACK@[1; 2)
META_ITEM@[2; 11)
IDENT@[2; 5)
L_PAREN@[5; 6)
META_ITEM@[6; 10)
IDENT@[6; 10)
R_PAREN@[10; 11)
R_BRACK@[11; 12)
WHITESPACE@[12; 13)
ATTR@[13; 23)
POUND@[13; 14)
L_BRACK@[14; 15)
META_ITEM@[15; 21)
IDENT@[15; 21)
R_BRACK@[21; 22)
WHITESPACE@[22; 23)
FN_ITEM@[23; 35)
FN_KW@[23; 25)
WHITESPACE@[25; 26)
IDENT@[26; 29)
L_PAREN@[29; 30)
R_PAREN@[30; 31)
WHITESPACE@[31; 32)
L_CURLY@[32; 33)
R_CURLY@[33; 34)
WHITESPACE@[34; 35)