From 9a8e9bc4c6339051ef260f7794603481b6ff0bf2 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 11 Jan 2018 23:01:12 +0300 Subject: G: item outer attributes --- src/parser/event_parser/grammar/attributes.rs | 18 ++++++++++------- src/parser/event_parser/grammar/items.rs | 2 +- src/parser/event_parser/grammar/mod.rs | 10 ++++++++- src/parser/event_parser/parser.rs | 4 ++++ tests/data/parser/ok/0011_outer_attribute.rs | 3 +++ tests/data/parser/ok/0011_outer_attribute.txt | 29 +++++++++++++++++++++++++++ 6 files changed, 57 insertions(+), 9 deletions(-) create mode 100644 tests/data/parser/ok/0011_outer_attribute.rs create mode 100644 tests/data/parser/ok/0011_outer_attribute.txt diff --git a/src/parser/event_parser/grammar/attributes.rs b/src/parser/event_parser/grammar/attributes.rs index 52210ccad..d774f8827 100644 --- a/src/parser/event_parser/grammar/attributes.rs +++ b/src/parser/event_parser/grammar/attributes.rs @@ -1,22 +1,26 @@ use super::*; +enum AttrKind { + Inner, Outer +} + 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) { meta_item(p) && p.expect(R_BRACK); } - if inner { - node_if(p, [POUND, EXCL, L_BRACK], ATTR, attr_tail) - } else { - node_if(p, [POUND, L_BRACK], ATTR, attr_tail) + match kind { + AttrKind::Inner => node_if(p, [POUND, EXCL, L_BRACK], ATTR, attr_tail), + AttrKind::Outer => node_if(p, [POUND, L_BRACK], ATTR, attr_tail), } } diff --git a/src/parser/event_parser/grammar/items.rs b/src/parser/event_parser/grammar/items.rs index 950e02a4d..522986ed0 100644 --- a/src/parser/event_parser/grammar/items.rs +++ b/src/parser/event_parser/grammar/items.rs @@ -12,7 +12,7 @@ pub(super) fn mod_contents(p: &mut Parser) { fn item_first(p: &Parser) -> bool { 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, } } diff --git a/src/parser/event_parser/grammar/mod.rs b/src/parser/event_parser/grammar/mod.rs index 60458ce70..76f62b714 100644 --- a/src/parser/event_parser/grammar/mod.rs +++ b/src/parser/event_parser/grammar/mod.rs @@ -41,7 +41,15 @@ fn node(p: &mut Parser, node_kind: SyntaxKind, rest: F) } fn many 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 bool>(p: &mut Parser, end: SyntaxKind, f: F) { diff --git a/src/parser/event_parser/parser.rs b/src/parser/event_parser/parser.rs index a1a0ebfea..d7d24fa27 100644 --- a/src/parser/event_parser/parser.rs +++ b/src/parser/event_parser/parser.rs @@ -44,6 +44,10 @@ impl<'t> Parser<'t> { } } + pub(crate) fn pos(&self) -> usize { + self.pos + } + pub(crate) fn into_events(self) -> Vec { assert!(self.curly_limit.is_none()); assert!(self.current() == EOF); diff --git a/tests/data/parser/ok/0011_outer_attribute.rs b/tests/data/parser/ok/0011_outer_attribute.rs new file mode 100644 index 000000000..8b80c0d90 --- /dev/null +++ b/tests/data/parser/ok/0011_outer_attribute.rs @@ -0,0 +1,3 @@ +#[cfg(test)] +#[ignore] +fn foo() {} diff --git a/tests/data/parser/ok/0011_outer_attribute.txt b/tests/data/parser/ok/0011_outer_attribute.txt new file mode 100644 index 000000000..a790f4095 --- /dev/null +++ b/tests/data/parser/ok/0011_outer_attribute.txt @@ -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) -- cgit v1.2.3