aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-01-07 18:40:18 +0000
committerAleksey Kladov <[email protected]>2018-01-07 18:40:18 +0000
commit7bc974ab2c29f896a0d9ca952ad306a9ed38f6f2 (patch)
tree2c39c8dcde0080a065ef0e8d59e5c4147b330a2b
parent5562931e4f3c6c57e9122c3ce34d941fb1ff6e5b (diff)
G: some attributes
-rw-r--r--grammar.ron1
-rw-r--r--src/parser/event_parser/grammar.rs52
-rw-r--r--src/syntax_kinds.rs4
-rw-r--r--tests/data/parser/ok/0006_inner_attributes.txt58
4 files changed, 83 insertions, 32 deletions
diff --git a/grammar.ron b/grammar.ron
index 39cb0a543..e3b450d2b 100644
--- a/grammar.ron
+++ b/grammar.ron
@@ -66,5 +66,6 @@ Grammar(
66 "STRUCT_FIELD", 66 "STRUCT_FIELD",
67 "FN_ITEM", 67 "FN_ITEM",
68 "ATTR", 68 "ATTR",
69 "META_ITEM",
69 ] 70 ]
70) \ No newline at end of file 71) \ No newline at end of file
diff --git a/src/parser/event_parser/grammar.rs b/src/parser/event_parser/grammar.rs
index 64c6718cb..acf27aec9 100644
--- a/src/parser/event_parser/grammar.rs
+++ b/src/parser/event_parser/grammar.rs
@@ -34,7 +34,7 @@ fn item(p: &mut Parser) {
34 34
35fn struct_item(p: &mut Parser) { 35fn struct_item(p: &mut Parser) {
36 p.expect(IDENT) 36 p.expect(IDENT)
37 && p.curly_block(|p| comma_list(p, struct_field)); 37 && p.curly_block(|p| comma_list(p, EOF, struct_field));
38} 38}
39 39
40fn struct_field(p: &mut Parser) -> bool { 40fn struct_field(p: &mut Parser) -> bool {
@@ -52,19 +52,45 @@ fn fn_item(p: &mut Parser) {
52// Paths, types, attributes, and stuff // 52// Paths, types, attributes, and stuff //
53 53
54fn inner_attributes(p: &mut Parser) { 54fn inner_attributes(p: &mut Parser) {
55 many(p, inner_attribute) 55 many(p, |p| attribute(p, true))
56} 56}
57 57
58fn inner_attribute(p: &mut Parser) -> bool { 58fn attribute(p: &mut Parser, inner: bool) -> bool {
59 if !(p.lookahead(&[EXCL, POUND])) { 59 let attr_start = inner && p.lookahead(&[POUND, EXCL, L_BRACK])
60 || !inner && p.lookahead(&[POUND, L_BRACK]);
61 if !attr_start {
60 return false; 62 return false;
61 } 63 }
62 node(p, ATTR, |p| { 64 node(p, ATTR, |p| {
63 p.bump_n(2); 65 p.bump_n(if inner { 3 } else { 2 });
66 meta_item(p) && p.expect(R_BRACK);
64 }); 67 });
65 true 68 true
66} 69}
67 70
71fn meta_item(p: &mut Parser) -> bool {
72 node_if(p, IDENT, META_ITEM, |p| {
73 if p.eat(EQ) {
74 if !literal(p) {
75 p.error()
76 .message("expected literal")
77 .emit();
78 }
79 } else if p.eat(L_PAREN) {
80 comma_list(p, R_PAREN, meta_item_inner);
81 p.expect(R_PAREN);
82 }
83 })
84}
85
86fn meta_item_inner(p: &mut Parser) -> bool {
87 meta_item(p) || literal(p)
88}
89
90fn literal(p: &mut Parser) -> bool {
91 p.eat(INT_NUMBER) || p.eat(FLOAT_NUMBER)
92}
93
68fn outer_attributes(_: &mut Parser) { 94fn outer_attributes(_: &mut Parser) {
69} 95}
70 96
@@ -75,7 +101,12 @@ fn visibility(_: &mut Parser) {
75 101
76// Error recovery and high-order utils // 102// Error recovery and high-order utils //
77 103
78fn node_if<F: FnOnce(&mut Parser)>(p: &mut Parser, first: SyntaxKind, node_kind: SyntaxKind, rest: F) -> bool { 104fn node_if<F: FnOnce(&mut Parser)>(
105 p: &mut Parser,
106 first: SyntaxKind,
107 node_kind: SyntaxKind,
108 rest: F
109) -> bool {
79 p.current() == first && { node(p, node_kind, |p| { p.bump(); rest(p); }); true } 110 p.current() == first && { node(p, node_kind, |p| { p.bump(); rest(p); }); true }
80} 111}
81 112
@@ -89,10 +120,9 @@ fn many<F: Fn(&mut Parser) -> bool>(p: &mut Parser, f: F) {
89 while f(p) { } 120 while f(p) { }
90} 121}
91 122
92fn comma_list<F: Fn(&mut Parser) -> bool>(p: &mut Parser, f: F) { 123fn comma_list<F: Fn(&mut Parser) -> bool>(p: &mut Parser, end: SyntaxKind, f: F) {
93 many(p, |p| { 124 many(p, |p| {
94 f(p); 125 if !f(p) || p.current() == end {
95 if p.current() == EOF {
96 false 126 false
97 } else { 127 } else {
98 p.expect(COMMA); 128 p.expect(COMMA);
@@ -157,4 +187,8 @@ impl<'p> Parser<'p> {
157 self.bump(); 187 self.bump();
158 } 188 }
159 } 189 }
190
191 fn eat(&mut self, kind: SyntaxKind) -> bool {
192 self.current() == kind && { self.bump(); true }
193 }
160} \ No newline at end of file 194} \ No newline at end of file
diff --git a/src/syntax_kinds.rs b/src/syntax_kinds.rs
index 67c840a3e..eea7819a3 100644
--- a/src/syntax_kinds.rs
+++ b/src/syntax_kinds.rs
@@ -63,8 +63,9 @@ pub const STRUCT_ITEM: SyntaxKind = SyntaxKind(58);
63pub const STRUCT_FIELD: SyntaxKind = SyntaxKind(59); 63pub const STRUCT_FIELD: SyntaxKind = SyntaxKind(59);
64pub const FN_ITEM: SyntaxKind = SyntaxKind(60); 64pub const FN_ITEM: SyntaxKind = SyntaxKind(60);
65pub const ATTR: SyntaxKind = SyntaxKind(61); 65pub const ATTR: SyntaxKind = SyntaxKind(61);
66pub const META_ITEM: SyntaxKind = SyntaxKind(62);
66 67
67static INFOS: [SyntaxInfo; 62] = [ 68static INFOS: [SyntaxInfo; 63] = [
68 SyntaxInfo { name: "USE_KW" }, 69 SyntaxInfo { name: "USE_KW" },
69 SyntaxInfo { name: "FN_KW" }, 70 SyntaxInfo { name: "FN_KW" },
70 SyntaxInfo { name: "STRUCT_KW" }, 71 SyntaxInfo { name: "STRUCT_KW" },
@@ -127,6 +128,7 @@ static INFOS: [SyntaxInfo; 62] = [
127 SyntaxInfo { name: "STRUCT_FIELD" }, 128 SyntaxInfo { name: "STRUCT_FIELD" },
128 SyntaxInfo { name: "FN_ITEM" }, 129 SyntaxInfo { name: "FN_ITEM" },
129 SyntaxInfo { name: "ATTR" }, 130 SyntaxInfo { name: "ATTR" },
131 SyntaxInfo { name: "META_ITEM" },
130]; 132];
131 133
132pub(crate) fn syntax_info(kind: SyntaxKind) -> &'static SyntaxInfo { 134pub(crate) fn syntax_info(kind: SyntaxKind) -> &'static SyntaxInfo {
diff --git a/tests/data/parser/ok/0006_inner_attributes.txt b/tests/data/parser/ok/0006_inner_attributes.txt
index c837979d1..a19d2f49c 100644
--- a/tests/data/parser/ok/0006_inner_attributes.txt
+++ b/tests/data/parser/ok/0006_inner_attributes.txt
@@ -1,44 +1,58 @@
1FILE@[0; 236) 1FILE@[0; 236)
2 ERROR@[0; 236) 2 ATTR@[0; 9)
3 err: `expected item`
4 POUND@[0; 1) 3 POUND@[0; 1)
5 EXCL@[1; 2) 4 EXCL@[1; 2)
6 L_BRACK@[2; 3) 5 L_BRACK@[2; 3)
7 IDENT@[3; 7) 6 META_ITEM@[3; 7)
7 IDENT@[3; 7)
8 R_BRACK@[7; 8) 8 R_BRACK@[7; 8)
9 WHITESPACE@[8; 9) 9 WHITESPACE@[8; 9)
10 ATTR@[9; 24)
10 POUND@[9; 10) 11 POUND@[9; 10)
11 EXCL@[10; 11) 12 EXCL@[10; 11)
12 L_BRACK@[11; 12) 13 L_BRACK@[11; 12)
13 IDENT@[12; 16) 14 META_ITEM@[12; 22)
14 L_PAREN@[16; 17) 15 IDENT@[12; 16)
15 IDENT@[17; 21) 16 L_PAREN@[16; 17)
16 R_PAREN@[21; 22) 17 META_ITEM@[17; 21)
18 IDENT@[17; 21)
19 R_PAREN@[21; 22)
17 R_BRACK@[22; 23) 20 R_BRACK@[22; 23)
18 WHITESPACE@[23; 24) 21 WHITESPACE@[23; 24)
22 ATTR@[24; 40)
19 POUND@[24; 25) 23 POUND@[24; 25)
20 EXCL@[25; 26) 24 EXCL@[25; 26)
21 L_BRACK@[26; 27) 25 L_BRACK@[26; 27)
22 IDENT@[27; 31) 26 META_ITEM@[27; 38)
23 L_PAREN@[31; 32) 27 IDENT@[27; 31)
24 IDENT@[32; 37) 28 L_PAREN@[31; 32)
25 R_PAREN@[37; 38) 29 META_ITEM@[32; 37)
30 IDENT@[32; 37)
31 R_PAREN@[37; 38)
26 R_BRACK@[38; 39) 32 R_BRACK@[38; 39)
27 WHITESPACE@[39; 40) 33 WHITESPACE@[39; 40)
34 ATTR@[40; 66)
28 POUND@[40; 41) 35 POUND@[40; 41)
29 EXCL@[41; 42) 36 EXCL@[41; 42)
30 L_BRACK@[42; 43) 37 L_BRACK@[42; 43)
31 IDENT@[43; 47) 38 META_ITEM@[43; 66)
32 L_PAREN@[47; 48) 39 IDENT@[43; 47)
33 IDENT@[48; 53) 40 L_PAREN@[47; 48)
34 COMMA@[53; 54) 41 META_ITEM@[48; 53)
35 WHITESPACE@[54; 55) 42 IDENT@[48; 53)
36 INT_NUMBER@[55; 58) 43 COMMA@[53; 54)
37 COMMA@[58; 59) 44 WHITESPACE@[54; 55)
38 WHITESPACE@[59; 60) 45 INT_NUMBER@[55; 58)
39 IDENT@[60; 64) 46 COMMA@[58; 59)
40 COMMA@[64; 65) 47 META_ITEM@[59; 64)
41 WHITESPACE@[65; 66) 48 WHITESPACE@[59; 60)
49 IDENT@[60; 64)
50 COMMA@[64; 65)
51 err: `expected R_PAREN`
52 WHITESPACE@[65; 66)
53 err: `expected R_BRACK`
54 ERROR@[66; 236)
55 err: `expected item`
42 STRING@[66; 72) 56 STRING@[66; 72)
43 COMMA@[72; 73) 57 COMMA@[72; 73)
44 WHITESPACE@[73; 74) 58 WHITESPACE@[73; 74)