aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-01-13 19:00:26 +0000
committerAleksey Kladov <[email protected]>2018-01-13 19:00:26 +0000
commit08f7c69f90bac772c69b3bf34877f3d9a845c541 (patch)
tree4866ac1ab988d1735ded745aacf1630f27a3220e
parent55891be06a1f0a051638cb59f1d15167faf5ab82 (diff)
G: struct flavors
-rw-r--r--grammar.ron4
-rw-r--r--src/parser/event_parser/grammar/items.rs86
-rw-r--r--src/parser/event_parser/grammar/mod.rs16
-rw-r--r--src/parser/event_parser/grammar/types.rs5
-rw-r--r--src/syntax_kinds.rs141
-rw-r--r--tests/data/lexer/0011_keywords.rs2
-rw-r--r--tests/data/lexer/0011_keywords.txt2
-rw-r--r--tests/data/parser/err/0000_struct_field_missing_comma.txt4
-rw-r--r--tests/data/parser/err/0003_C++_semicolon.txt4
-rw-r--r--tests/data/parser/ok/0002_struct_item_field.txt2
-rw-r--r--tests/data/parser/ok/0016_struct_flavors.rs10
-rw-r--r--tests/data/parser/ok/0016_struct_flavors.txt66
12 files changed, 257 insertions, 85 deletions
diff --git a/grammar.ron b/grammar.ron
index fe0ec8406..70e269e20 100644
--- a/grammar.ron
+++ b/grammar.ron
@@ -16,6 +16,7 @@ Grammar(
16 "self", 16 "self",
17 "super", 17 "super",
18 "in", 18 "in",
19 "where",
19 ], 20 ],
20 tokens: [ 21 tokens: [
21 "ERROR", 22 "ERROR",
@@ -73,7 +74,8 @@ Grammar(
73 nodes: [ 74 nodes: [
74 "FILE", 75 "FILE",
75 "STRUCT_ITEM", 76 "STRUCT_ITEM",
76 "STRUCT_FIELD", 77 "NAMED_FIELD",
78 "POS_FIELD",
77 "FN_ITEM", 79 "FN_ITEM",
78 "EXTERN_CRATE_ITEM", 80 "EXTERN_CRATE_ITEM",
79 "ATTR", 81 "ATTR",
diff --git a/src/parser/event_parser/grammar/items.rs b/src/parser/event_parser/grammar/items.rs
index 2f64111ab..a14f6de77 100644
--- a/src/parser/event_parser/grammar/items.rs
+++ b/src/parser/event_parser/grammar/items.rs
@@ -56,8 +56,84 @@ fn item(p: &mut Parser) -> bool {
56} 56}
57 57
58fn struct_item(p: &mut Parser) { 58fn struct_item(p: &mut Parser) {
59 p.expect(IDENT) 59 if !p.expect(IDENT) {
60 && p.curly_block(|p| comma_list(p, EOF, struct_field)); 60 return
61 }
62 generic_parameters(p);
63 match p.current() {
64 WHERE_KW => {
65 where_clause(p);
66 match p.current() {
67 SEMI => {
68 p.bump();
69 return
70 }
71 L_CURLY => named_fields(p),
72 _ => { //TODO: special case `(` error message
73 p.error()
74 .message("expected `;` or `{`")
75 .emit();
76 return
77 }
78 }
79 }
80 SEMI => {
81 p.bump();
82 return
83 }
84 L_CURLY => named_fields(p),
85 L_PAREN => {
86 tuple_fields(p);
87 p.expect(SEMI);
88 },
89 _ => {
90 p.error()
91 .message("expected `;`, `{`, or `(`")
92 .emit();
93 return
94 }
95 }
96}
97
98fn named_fields(p: &mut Parser) {
99 p.curly_block(|p| comma_list(p, EOF, |p| {
100 named_field(p);
101 true
102 }));
103
104 fn named_field(p: &mut Parser) {
105 node(p, NAMED_FIELD, |p| {
106 visibility(p);
107 p.expect(IDENT) && p.expect(COLON) && {
108 types::type_ref(p);
109 true
110 };
111 })
112 }
113}
114
115fn tuple_fields(p: &mut Parser) {
116 if !p.expect(L_PAREN) {
117 return
118 }
119 comma_list(p, R_PAREN, |p| {
120 tuple_field(p);
121 true
122 });
123 p.expect(R_PAREN);
124
125 fn tuple_field(p: &mut Parser) {
126 node(p, POS_FIELD, |p| {
127 visibility(p);
128 types::type_ref(p);
129 })
130 }
131}
132
133fn generic_parameters(_: &mut Parser) {
134}
135
136fn where_clause(_: &mut Parser) {
61} 137}
62 138
63fn extern_crate_item(p: &mut Parser) { 139fn extern_crate_item(p: &mut Parser) {
@@ -133,11 +209,7 @@ fn use_item(p: &mut Parser) {
133 } 209 }
134} 210}
135 211
136fn struct_field(p: &mut Parser) -> bool { 212
137 node_if(p, IDENT, STRUCT_FIELD, |p| {
138 p.expect(COLON) && p.expect(IDENT);
139 })
140}
141 213
142fn fn_item(p: &mut Parser) { 214fn fn_item(p: &mut Parser) {
143 p.expect(IDENT) && p.expect(L_PAREN) && p.expect(R_PAREN) 215 p.expect(IDENT) && p.expect(L_PAREN) && p.expect(R_PAREN)
diff --git a/src/parser/event_parser/grammar/mod.rs b/src/parser/event_parser/grammar/mod.rs
index 1c57e0cb4..881bb3ef3 100644
--- a/src/parser/event_parser/grammar/mod.rs
+++ b/src/parser/event_parser/grammar/mod.rs
@@ -6,6 +6,7 @@ use syntax_kinds::*;
6mod items; 6mod items;
7mod attributes; 7mod attributes;
8mod expressions; 8mod expressions;
9mod types;
9mod paths; 10mod paths;
10 11
11pub(crate) fn file(p: &mut Parser) { 12pub(crate) fn file(p: &mut Parser) {
@@ -72,12 +73,21 @@ fn many<F: FnMut(&mut Parser) -> bool>(p: &mut Parser, mut f: F) {
72 73
73fn comma_list<F: Fn(&mut Parser) -> bool>(p: &mut Parser, end: SyntaxKind, f: F) { 74fn comma_list<F: Fn(&mut Parser) -> bool>(p: &mut Parser, end: SyntaxKind, f: F) {
74 many(p, |p| { 75 many(p, |p| {
75 if !f(p) || p.current() == end { 76 if p.current() == end {
76 false 77 return false
78 }
79 let pos = p.pos();
80 f(p);
81 if p.pos() == pos {
82 return false
83 }
84
85 if p.current() == end {
86 p.eat(COMMA);
77 } else { 87 } else {
78 p.expect(COMMA); 88 p.expect(COMMA);
79 true
80 } 89 }
90 true
81 }) 91 })
82} 92}
83 93
diff --git a/src/parser/event_parser/grammar/types.rs b/src/parser/event_parser/grammar/types.rs
new file mode 100644
index 000000000..c431643d7
--- /dev/null
+++ b/src/parser/event_parser/grammar/types.rs
@@ -0,0 +1,5 @@
1use super::*;
2
3pub(super) fn type_ref(p: &mut Parser) {
4 p.expect(IDENT);
5} \ No newline at end of file
diff --git a/src/syntax_kinds.rs b/src/syntax_kinds.rs
index 8bc63a210..5ab8b934b 100644
--- a/src/syntax_kinds.rs
+++ b/src/syntax_kinds.rs
@@ -17,74 +17,76 @@ pub const PUB_KW: SyntaxKind = SyntaxKind(12);
17pub const SELF_KW: SyntaxKind = SyntaxKind(13); 17pub const SELF_KW: SyntaxKind = SyntaxKind(13);
18pub const SUPER_KW: SyntaxKind = SyntaxKind(14); 18pub const SUPER_KW: SyntaxKind = SyntaxKind(14);
19pub const IN_KW: SyntaxKind = SyntaxKind(15); 19pub const IN_KW: SyntaxKind = SyntaxKind(15);
20pub const ERROR: SyntaxKind = SyntaxKind(16); 20pub const WHERE_KW: SyntaxKind = SyntaxKind(16);
21pub const IDENT: SyntaxKind = SyntaxKind(17); 21pub const ERROR: SyntaxKind = SyntaxKind(17);
22pub const UNDERSCORE: SyntaxKind = SyntaxKind(18); 22pub const IDENT: SyntaxKind = SyntaxKind(18);
23pub const WHITESPACE: SyntaxKind = SyntaxKind(19); 23pub const UNDERSCORE: SyntaxKind = SyntaxKind(19);
24pub const INT_NUMBER: SyntaxKind = SyntaxKind(20); 24pub const WHITESPACE: SyntaxKind = SyntaxKind(20);
25pub const FLOAT_NUMBER: SyntaxKind = SyntaxKind(21); 25pub const INT_NUMBER: SyntaxKind = SyntaxKind(21);
26pub const SEMI: SyntaxKind = SyntaxKind(22); 26pub const FLOAT_NUMBER: SyntaxKind = SyntaxKind(22);
27pub const COMMA: SyntaxKind = SyntaxKind(23); 27pub const SEMI: SyntaxKind = SyntaxKind(23);
28pub const DOT: SyntaxKind = SyntaxKind(24); 28pub const COMMA: SyntaxKind = SyntaxKind(24);
29pub const DOTDOT: SyntaxKind = SyntaxKind(25); 29pub const DOT: SyntaxKind = SyntaxKind(25);
30pub const DOTDOTDOT: SyntaxKind = SyntaxKind(26); 30pub const DOTDOT: SyntaxKind = SyntaxKind(26);
31pub const DOTDOTEQ: SyntaxKind = SyntaxKind(27); 31pub const DOTDOTDOT: SyntaxKind = SyntaxKind(27);
32pub const L_PAREN: SyntaxKind = SyntaxKind(28); 32pub const DOTDOTEQ: SyntaxKind = SyntaxKind(28);
33pub const R_PAREN: SyntaxKind = SyntaxKind(29); 33pub const L_PAREN: SyntaxKind = SyntaxKind(29);
34pub const L_CURLY: SyntaxKind = SyntaxKind(30); 34pub const R_PAREN: SyntaxKind = SyntaxKind(30);
35pub const R_CURLY: SyntaxKind = SyntaxKind(31); 35pub const L_CURLY: SyntaxKind = SyntaxKind(31);
36pub const L_BRACK: SyntaxKind = SyntaxKind(32); 36pub const R_CURLY: SyntaxKind = SyntaxKind(32);
37pub const R_BRACK: SyntaxKind = SyntaxKind(33); 37pub const L_BRACK: SyntaxKind = SyntaxKind(33);
38pub const L_ANGLE: SyntaxKind = SyntaxKind(34); 38pub const R_BRACK: SyntaxKind = SyntaxKind(34);
39pub const R_ANGLE: SyntaxKind = SyntaxKind(35); 39pub const L_ANGLE: SyntaxKind = SyntaxKind(35);
40pub const AT: SyntaxKind = SyntaxKind(36); 40pub const R_ANGLE: SyntaxKind = SyntaxKind(36);
41pub const POUND: SyntaxKind = SyntaxKind(37); 41pub const AT: SyntaxKind = SyntaxKind(37);
42pub const TILDE: SyntaxKind = SyntaxKind(38); 42pub const POUND: SyntaxKind = SyntaxKind(38);
43pub const QUESTION: SyntaxKind = SyntaxKind(39); 43pub const TILDE: SyntaxKind = SyntaxKind(39);
44pub const COLON: SyntaxKind = SyntaxKind(40); 44pub const QUESTION: SyntaxKind = SyntaxKind(40);
45pub const COLONCOLON: SyntaxKind = SyntaxKind(41); 45pub const COLON: SyntaxKind = SyntaxKind(41);
46pub const DOLLAR: SyntaxKind = SyntaxKind(42); 46pub const COLONCOLON: SyntaxKind = SyntaxKind(42);
47pub const EQ: SyntaxKind = SyntaxKind(43); 47pub const DOLLAR: SyntaxKind = SyntaxKind(43);
48pub const EQEQ: SyntaxKind = SyntaxKind(44); 48pub const EQ: SyntaxKind = SyntaxKind(44);
49pub const FAT_ARROW: SyntaxKind = SyntaxKind(45); 49pub const EQEQ: SyntaxKind = SyntaxKind(45);
50pub const NEQ: SyntaxKind = SyntaxKind(46); 50pub const FAT_ARROW: SyntaxKind = SyntaxKind(46);
51pub const EXCL: SyntaxKind = SyntaxKind(47); 51pub const NEQ: SyntaxKind = SyntaxKind(47);
52pub const LIFETIME: SyntaxKind = SyntaxKind(48); 52pub const EXCL: SyntaxKind = SyntaxKind(48);
53pub const CHAR: SyntaxKind = SyntaxKind(49); 53pub const LIFETIME: SyntaxKind = SyntaxKind(49);
54pub const BYTE: SyntaxKind = SyntaxKind(50); 54pub const CHAR: SyntaxKind = SyntaxKind(50);
55pub const STRING: SyntaxKind = SyntaxKind(51); 55pub const BYTE: SyntaxKind = SyntaxKind(51);
56pub const RAW_STRING: SyntaxKind = SyntaxKind(52); 56pub const STRING: SyntaxKind = SyntaxKind(52);
57pub const BYTE_STRING: SyntaxKind = SyntaxKind(53); 57pub const RAW_STRING: SyntaxKind = SyntaxKind(53);
58pub const RAW_BYTE_STRING: SyntaxKind = SyntaxKind(54); 58pub const BYTE_STRING: SyntaxKind = SyntaxKind(54);
59pub const PLUS: SyntaxKind = SyntaxKind(55); 59pub const RAW_BYTE_STRING: SyntaxKind = SyntaxKind(55);
60pub const MINUS: SyntaxKind = SyntaxKind(56); 60pub const PLUS: SyntaxKind = SyntaxKind(56);
61pub const STAR: SyntaxKind = SyntaxKind(57); 61pub const MINUS: SyntaxKind = SyntaxKind(57);
62pub const SLASH: SyntaxKind = SyntaxKind(58); 62pub const STAR: SyntaxKind = SyntaxKind(58);
63pub const CARET: SyntaxKind = SyntaxKind(59); 63pub const SLASH: SyntaxKind = SyntaxKind(59);
64pub const PERCENT: SyntaxKind = SyntaxKind(60); 64pub const CARET: SyntaxKind = SyntaxKind(60);
65pub const AMPERSAND: SyntaxKind = SyntaxKind(61); 65pub const PERCENT: SyntaxKind = SyntaxKind(61);
66pub const PIPE: SyntaxKind = SyntaxKind(62); 66pub const AMPERSAND: SyntaxKind = SyntaxKind(62);
67pub const THIN_ARROW: SyntaxKind = SyntaxKind(63); 67pub const PIPE: SyntaxKind = SyntaxKind(63);
68pub const COMMENT: SyntaxKind = SyntaxKind(64); 68pub const THIN_ARROW: SyntaxKind = SyntaxKind(64);
69pub const DOC_COMMENT: SyntaxKind = SyntaxKind(65); 69pub const COMMENT: SyntaxKind = SyntaxKind(65);
70pub const SHEBANG: SyntaxKind = SyntaxKind(66); 70pub const DOC_COMMENT: SyntaxKind = SyntaxKind(66);
71pub const FILE: SyntaxKind = SyntaxKind(67); 71pub const SHEBANG: SyntaxKind = SyntaxKind(67);
72pub const STRUCT_ITEM: SyntaxKind = SyntaxKind(68); 72pub const FILE: SyntaxKind = SyntaxKind(68);
73pub const STRUCT_FIELD: SyntaxKind = SyntaxKind(69); 73pub const STRUCT_ITEM: SyntaxKind = SyntaxKind(69);
74pub const FN_ITEM: SyntaxKind = SyntaxKind(70); 74pub const NAMED_FIELD: SyntaxKind = SyntaxKind(70);
75pub const EXTERN_CRATE_ITEM: SyntaxKind = SyntaxKind(71); 75pub const POS_FIELD: SyntaxKind = SyntaxKind(71);
76pub const ATTR: SyntaxKind = SyntaxKind(72); 76pub const FN_ITEM: SyntaxKind = SyntaxKind(72);
77pub const META_ITEM: SyntaxKind = SyntaxKind(73); 77pub const EXTERN_CRATE_ITEM: SyntaxKind = SyntaxKind(73);
78pub const MOD_ITEM: SyntaxKind = SyntaxKind(74); 78pub const ATTR: SyntaxKind = SyntaxKind(74);
79pub const USE_ITEM: SyntaxKind = SyntaxKind(75); 79pub const META_ITEM: SyntaxKind = SyntaxKind(75);
80pub const USE_TREE: SyntaxKind = SyntaxKind(76); 80pub const MOD_ITEM: SyntaxKind = SyntaxKind(76);
81pub const PATH: SyntaxKind = SyntaxKind(77); 81pub const USE_ITEM: SyntaxKind = SyntaxKind(77);
82pub const PATH_SEGMENT: SyntaxKind = SyntaxKind(78); 82pub const USE_TREE: SyntaxKind = SyntaxKind(78);
83pub const LITERAL: SyntaxKind = SyntaxKind(79); 83pub const PATH: SyntaxKind = SyntaxKind(79);
84pub const ALIAS: SyntaxKind = SyntaxKind(80); 84pub const PATH_SEGMENT: SyntaxKind = SyntaxKind(80);
85pub const VISIBILITY: SyntaxKind = SyntaxKind(81); 85pub const LITERAL: SyntaxKind = SyntaxKind(81);
86pub const ALIAS: SyntaxKind = SyntaxKind(82);
87pub const VISIBILITY: SyntaxKind = SyntaxKind(83);
86 88
87static INFOS: [SyntaxInfo; 82] = [ 89static INFOS: [SyntaxInfo; 84] = [
88 SyntaxInfo { name: "USE_KW" }, 90 SyntaxInfo { name: "USE_KW" },
89 SyntaxInfo { name: "FN_KW" }, 91 SyntaxInfo { name: "FN_KW" },
90 SyntaxInfo { name: "STRUCT_KW" }, 92 SyntaxInfo { name: "STRUCT_KW" },
@@ -101,6 +103,7 @@ static INFOS: [SyntaxInfo; 82] = [
101 SyntaxInfo { name: "SELF_KW" }, 103 SyntaxInfo { name: "SELF_KW" },
102 SyntaxInfo { name: "SUPER_KW" }, 104 SyntaxInfo { name: "SUPER_KW" },
103 SyntaxInfo { name: "IN_KW" }, 105 SyntaxInfo { name: "IN_KW" },
106 SyntaxInfo { name: "WHERE_KW" },
104 SyntaxInfo { name: "ERROR" }, 107 SyntaxInfo { name: "ERROR" },
105 SyntaxInfo { name: "IDENT" }, 108 SyntaxInfo { name: "IDENT" },
106 SyntaxInfo { name: "UNDERSCORE" }, 109 SyntaxInfo { name: "UNDERSCORE" },
@@ -154,7 +157,8 @@ static INFOS: [SyntaxInfo; 82] = [
154 SyntaxInfo { name: "SHEBANG" }, 157 SyntaxInfo { name: "SHEBANG" },
155 SyntaxInfo { name: "FILE" }, 158 SyntaxInfo { name: "FILE" },
156 SyntaxInfo { name: "STRUCT_ITEM" }, 159 SyntaxInfo { name: "STRUCT_ITEM" },
157 SyntaxInfo { name: "STRUCT_FIELD" }, 160 SyntaxInfo { name: "NAMED_FIELD" },
161 SyntaxInfo { name: "POS_FIELD" },
158 SyntaxInfo { name: "FN_ITEM" }, 162 SyntaxInfo { name: "FN_ITEM" },
159 SyntaxInfo { name: "EXTERN_CRATE_ITEM" }, 163 SyntaxInfo { name: "EXTERN_CRATE_ITEM" },
160 SyntaxInfo { name: "ATTR" }, 164 SyntaxInfo { name: "ATTR" },
@@ -191,6 +195,7 @@ pub(crate) fn ident_to_keyword(ident: &str) -> Option<SyntaxKind> {
191 "self" => Some(SELF_KW), 195 "self" => Some(SELF_KW),
192 "super" => Some(SUPER_KW), 196 "super" => Some(SUPER_KW),
193 "in" => Some(IN_KW), 197 "in" => Some(IN_KW),
198 "where" => Some(WHERE_KW),
194 _ => None, 199 _ => None,
195 } 200 }
196} 201}
diff --git a/tests/data/lexer/0011_keywords.rs b/tests/data/lexer/0011_keywords.rs
index aa729cdbd..c2c9e5667 100644
--- a/tests/data/lexer/0011_keywords.rs
+++ b/tests/data/lexer/0011_keywords.rs
@@ -1 +1 @@
fn use struct trait enum impl true false as extern crate mod pub self super in fn use struct trait enum impl true false as extern crate mod pub self super in where
diff --git a/tests/data/lexer/0011_keywords.txt b/tests/data/lexer/0011_keywords.txt
index 8a1f525ac..301ee21e2 100644
--- a/tests/data/lexer/0011_keywords.txt
+++ b/tests/data/lexer/0011_keywords.txt
@@ -29,4 +29,6 @@ WHITESPACE 1 " "
29SUPER_KW 5 "super" 29SUPER_KW 5 "super"
30WHITESPACE 1 " " 30WHITESPACE 1 " "
31IN_KW 2 "in" 31IN_KW 2 "in"
32WHITESPACE 1 " "
33WHERE_KW 5 "where"
32WHITESPACE 1 "\n" 34WHITESPACE 1 "\n"
diff --git a/tests/data/parser/err/0000_struct_field_missing_comma.txt b/tests/data/parser/err/0000_struct_field_missing_comma.txt
index 55a4ad915..f59205f55 100644
--- a/tests/data/parser/err/0000_struct_field_missing_comma.txt
+++ b/tests/data/parser/err/0000_struct_field_missing_comma.txt
@@ -5,7 +5,7 @@ FILE@[0; 34)
5 IDENT@[7; 8) 5 IDENT@[7; 8)
6 WHITESPACE@[8; 9) 6 WHITESPACE@[8; 9)
7 L_CURLY@[9; 10) 7 L_CURLY@[9; 10)
8 STRUCT_FIELD@[10; 26) 8 NAMED_FIELD@[10; 26)
9 WHITESPACE@[10; 15) 9 WHITESPACE@[10; 15)
10 IDENT@[15; 16) 10 IDENT@[15; 16)
11 COLON@[16; 17) 11 COLON@[16; 17)
@@ -13,7 +13,7 @@ FILE@[0; 34)
13 IDENT@[18; 21) 13 IDENT@[18; 21)
14 WHITESPACE@[21; 26) 14 WHITESPACE@[21; 26)
15 err: `expected COMMA` 15 err: `expected COMMA`
16 STRUCT_FIELD@[26; 33) 16 NAMED_FIELD@[26; 33)
17 IDENT@[26; 27) 17 IDENT@[26; 27)
18 COLON@[27; 28) 18 COLON@[27; 28)
19 WHITESPACE@[28; 29) 19 WHITESPACE@[28; 29)
diff --git a/tests/data/parser/err/0003_C++_semicolon.txt b/tests/data/parser/err/0003_C++_semicolon.txt
index 9308bb330..8dd45d2e5 100644
--- a/tests/data/parser/err/0003_C++_semicolon.txt
+++ b/tests/data/parser/err/0003_C++_semicolon.txt
@@ -5,14 +5,14 @@ FILE@[0; 40)
5 IDENT@[7; 8) 5 IDENT@[7; 8)
6 WHITESPACE@[8; 9) 6 WHITESPACE@[8; 9)
7 L_CURLY@[9; 10) 7 L_CURLY@[9; 10)
8 STRUCT_FIELD@[10; 21) 8 NAMED_FIELD@[10; 21)
9 WHITESPACE@[10; 15) 9 WHITESPACE@[10; 15)
10 IDENT@[15; 16) 10 IDENT@[15; 16)
11 COLON@[16; 17) 11 COLON@[16; 17)
12 WHITESPACE@[17; 18) 12 WHITESPACE@[17; 18)
13 IDENT@[18; 21) 13 IDENT@[18; 21)
14 COMMA@[21; 22) 14 COMMA@[21; 22)
15 STRUCT_FIELD@[22; 36) 15 NAMED_FIELD@[22; 36)
16 WHITESPACE@[22; 27) 16 WHITESPACE@[22; 27)
17 IDENT@[27; 28) 17 IDENT@[27; 28)
18 COLON@[28; 29) 18 COLON@[28; 29)
diff --git a/tests/data/parser/ok/0002_struct_item_field.txt b/tests/data/parser/ok/0002_struct_item_field.txt
index 87ab3f7a9..58042f6a7 100644
--- a/tests/data/parser/ok/0002_struct_item_field.txt
+++ b/tests/data/parser/ok/0002_struct_item_field.txt
@@ -5,7 +5,7 @@ FILE@[0; 25)
5 IDENT@[7; 8) 5 IDENT@[7; 8)
6 WHITESPACE@[8; 9) 6 WHITESPACE@[8; 9)
7 L_CURLY@[9; 10) 7 L_CURLY@[9; 10)
8 STRUCT_FIELD@[10; 24) 8 NAMED_FIELD@[10; 24)
9 WHITESPACE@[10; 15) 9 WHITESPACE@[10; 15)
10 IDENT@[15; 18) 10 IDENT@[15; 18)
11 COLON@[18; 19) 11 COLON@[18; 19)
diff --git a/tests/data/parser/ok/0016_struct_flavors.rs b/tests/data/parser/ok/0016_struct_flavors.rs
new file mode 100644
index 000000000..69638350c
--- /dev/null
+++ b/tests/data/parser/ok/0016_struct_flavors.rs
@@ -0,0 +1,10 @@
1struct A;
2struct B {}
3struct C();
4
5struct D {
6 a: u32,
7 pub b: u32
8}
9
10struct E(pub x, y,);
diff --git a/tests/data/parser/ok/0016_struct_flavors.txt b/tests/data/parser/ok/0016_struct_flavors.txt
new file mode 100644
index 000000000..93b16e1b9
--- /dev/null
+++ b/tests/data/parser/ok/0016_struct_flavors.txt
@@ -0,0 +1,66 @@
1FILE@[0; 97)
2 STRUCT_ITEM@[0; 10)
3 STRUCT_KW@[0; 6)
4 WHITESPACE@[6; 7)
5 IDENT@[7; 8)
6 SEMI@[8; 9)
7 WHITESPACE@[9; 10)
8 STRUCT_ITEM@[10; 22)
9 STRUCT_KW@[10; 16)
10 WHITESPACE@[16; 17)
11 IDENT@[17; 18)
12 WHITESPACE@[18; 19)
13 L_CURLY@[19; 20)
14 R_CURLY@[20; 21)
15 WHITESPACE@[21; 22)
16 STRUCT_ITEM@[22; 35)
17 STRUCT_KW@[22; 28)
18 WHITESPACE@[28; 29)
19 IDENT@[29; 30)
20 L_PAREN@[30; 31)
21 R_PAREN@[31; 32)
22 SEMI@[32; 33)
23 WHITESPACE@[33; 35)
24 STRUCT_ITEM@[35; 76)
25 STRUCT_KW@[35; 41)
26 WHITESPACE@[41; 42)
27 IDENT@[42; 43)
28 WHITESPACE@[43; 44)
29 L_CURLY@[44; 45)
30 NAMED_FIELD@[45; 56)
31 WHITESPACE@[45; 50)
32 IDENT@[50; 51)
33 COLON@[51; 52)
34 WHITESPACE@[52; 53)
35 IDENT@[53; 56)
36 COMMA@[56; 57)
37 NAMED_FIELD@[57; 73)
38 VISIBILITY@[57; 66)
39 WHITESPACE@[57; 62)
40 PUB_KW@[62; 65)
41 WHITESPACE@[65; 66)
42 IDENT@[66; 67)
43 COLON@[67; 68)
44 WHITESPACE@[68; 69)
45 IDENT@[69; 72)
46 WHITESPACE@[72; 73)
47 R_CURLY@[73; 74)
48 WHITESPACE@[74; 76)
49 STRUCT_ITEM@[76; 97)
50 STRUCT_KW@[76; 82)
51 WHITESPACE@[82; 83)
52 IDENT@[83; 84)
53 L_PAREN@[84; 85)
54 POS_FIELD@[85; 90)
55 VISIBILITY@[85; 89)
56 PUB_KW@[85; 88)
57 WHITESPACE@[88; 89)
58 IDENT@[89; 90)
59 COMMA@[90; 91)
60 POS_FIELD@[91; 93)
61 WHITESPACE@[91; 92)
62 IDENT@[92; 93)
63 COMMA@[93; 94)
64 R_PAREN@[94; 95)
65 SEMI@[95; 96)
66 WHITESPACE@[96; 97)