aboutsummaryrefslogtreecommitdiff
path: root/src/parser
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser')
-rw-r--r--src/parser/event_parser/grammar/items/mod.rs143
-rw-r--r--src/parser/event_parser/grammar/items/structs.rs8
-rw-r--r--src/parser/event_parser/grammar/items/use_item.rs66
-rw-r--r--src/parser/event_parser/grammar/mod.rs1
-rw-r--r--src/parser/event_parser/grammar/paths.rs6
-rw-r--r--src/parser/event_parser/grammar/type_params.rs75
6 files changed, 153 insertions, 146 deletions
diff --git a/src/parser/event_parser/grammar/items/mod.rs b/src/parser/event_parser/grammar/items/mod.rs
index a6d8f375c..35825e7c4 100644
--- a/src/parser/event_parser/grammar/items/mod.rs
+++ b/src/parser/event_parser/grammar/items/mod.rs
@@ -1,6 +1,7 @@
1use super::*; 1use super::*;
2 2
3mod structs; 3mod structs;
4mod use_item;
4 5
5pub(super) fn mod_contents(p: &mut Parser, stop_on_r_curly: bool) { 6pub(super) fn mod_contents(p: &mut Parser, stop_on_r_curly: bool) {
6 attributes::inner_attributes(p); 7 attributes::inner_attributes(p);
@@ -20,7 +21,7 @@ fn item(p: &mut Parser) {
20 let la = p.nth(1); 21 let la = p.nth(1);
21 let item_kind = match p.current() { 22 let item_kind = match p.current() {
22 USE_KW => { 23 USE_KW => {
23 use_item(p); 24 use_item::use_item(p);
24 USE_ITEM 25 USE_ITEM
25 } 26 }
26 EXTERN_KW if la == CRATE_KW => { 27 EXTERN_KW if la == CRATE_KW => {
@@ -82,76 +83,6 @@ fn item(p: &mut Parser) {
82 item.complete(p, item_kind); 83 item.complete(p, item_kind);
83} 84}
84 85
85fn type_param_list(p: &mut Parser) {
86 if !p.at(L_ANGLE) {
87 return;
88 }
89 let m = p.start();
90 p.bump();
91
92 while !p.at(EOF) && !p.at(R_ANGLE) {
93 match p.current() {
94 LIFETIME => lifetime_param(p),
95 IDENT => type_param(p),
96 _ => p.err_and_bump("expected type parameter"),
97 }
98 if !p.at(R_ANGLE) && !p.expect(COMMA) {
99 break;
100 }
101 }
102 p.expect(R_ANGLE);
103 m.complete(p, TYPE_PARAM_LIST);
104
105 fn lifetime_param(p: &mut Parser) {
106 assert!(p.at(LIFETIME));
107 let m = p.start();
108 p.bump();
109 if p.eat(COLON) {
110 while p.at(LIFETIME) {
111 p.bump();
112 if !p.eat(PLUS) {
113 break;
114 }
115 }
116 }
117 m.complete(p, LIFETIME_PARAM);
118 }
119
120 fn type_param(p: &mut Parser) {
121 assert!(p.at(IDENT));
122 let m = p.start();
123 p.bump();
124 if p.eat(COLON) {
125 loop {
126 let has_paren = p.eat(L_PAREN);
127 p.eat(QUESTION);
128 if p.at(FOR_KW) {
129 //TODO
130 }
131 if p.at(LIFETIME) {
132 p.bump();
133 } else if paths::is_path_start(p) {
134 paths::type_path(p);
135 } else {
136 break;
137 }
138 if has_paren {
139 p.expect(R_PAREN);
140 }
141 if !p.eat(PLUS) {
142 break;
143 }
144 }
145 }
146 if p.at(EQ) {
147 types::type_ref(p)
148 }
149 m.complete(p, TYPE_PARAM);
150 }
151}
152
153fn where_clause(_: &mut Parser) {}
154
155fn extern_crate_item(p: &mut Parser) { 86fn extern_crate_item(p: &mut Parser) {
156 assert!(p.at(EXTERN_KW)); 87 assert!(p.at(EXTERN_KW));
157 p.bump(); 88 p.bump();
@@ -179,76 +110,6 @@ fn extern_block(p: &mut Parser) {
179 p.expect(R_CURLY); 110 p.expect(R_CURLY);
180} 111}
181 112
182pub(super) fn is_use_tree_start(kind: SyntaxKind) -> bool {
183 kind == STAR || kind == L_CURLY
184}
185
186fn use_item(p: &mut Parser) {
187 assert!(p.at(USE_KW));
188 p.bump();
189
190 use_tree(p);
191 p.expect(SEMI);
192
193 fn use_tree(p: &mut Parser) {
194 let la = p.nth(1);
195 let m = p.start();
196 match (p.current(), la) {
197 (STAR, _) => p.bump(),
198 (COLONCOLON, STAR) => {
199 p.bump();
200 p.bump();
201 }
202 (L_CURLY, _) | (COLONCOLON, L_CURLY) => {
203 if p.at(COLONCOLON) {
204 p.bump();
205 }
206 nested_trees(p);
207 }
208 _ if paths::is_path_start(p) => {
209 paths::use_path(p);
210 match p.current() {
211 AS_KW => {
212 alias(p);
213 }
214 COLONCOLON => {
215 p.bump();
216 match p.current() {
217 STAR => {
218 p.bump();
219 }
220 L_CURLY => nested_trees(p),
221 _ => {
222 // is this unreachable?
223 p.error().message("expected `{` or `*`").emit();
224 }
225 }
226 }
227 _ => (),
228 }
229 }
230 _ => {
231 m.abandon(p);
232 p.err_and_bump("expected one of `*`, `::`, `{`, `self`, `super`, `indent`");
233 return;
234 }
235 }
236 m.complete(p, USE_TREE);
237 }
238
239 fn nested_trees(p: &mut Parser) {
240 assert!(p.at(L_CURLY));
241 p.bump();
242 while !p.at(EOF) && !p.at(R_CURLY) {
243 use_tree(p);
244 if !p.at(R_CURLY) {
245 p.expect(COMMA);
246 }
247 }
248 p.expect(R_CURLY);
249 }
250}
251
252fn abi(p: &mut Parser) { 113fn abi(p: &mut Parser) {
253 assert!(p.at(EXTERN_KW)); 114 assert!(p.at(EXTERN_KW));
254 let abi = p.start(); 115 let abi = p.start();
diff --git a/src/parser/event_parser/grammar/items/structs.rs b/src/parser/event_parser/grammar/items/structs.rs
index 6e438413b..69d95c698 100644
--- a/src/parser/event_parser/grammar/items/structs.rs
+++ b/src/parser/event_parser/grammar/items/structs.rs
@@ -7,10 +7,10 @@ pub(super) fn struct_item(p: &mut Parser) {
7 if !p.expect(IDENT) { 7 if !p.expect(IDENT) {
8 return; 8 return;
9 } 9 }
10 type_param_list(p); 10 type_params::list(p);
11 match p.current() { 11 match p.current() {
12 WHERE_KW => { 12 WHERE_KW => {
13 where_clause(p); 13 type_params::where_clause(p);
14 match p.current() { 14 match p.current() {
15 SEMI => { 15 SEMI => {
16 p.bump(); 16 p.bump();
@@ -44,8 +44,8 @@ pub(super) fn enum_item(p: &mut Parser) {
44 assert!(p.at(ENUM_KW)); 44 assert!(p.at(ENUM_KW));
45 p.bump(); 45 p.bump();
46 p.expect(IDENT); 46 p.expect(IDENT);
47 type_param_list(p); 47 type_params::list(p);
48 where_clause(p); 48 type_params::where_clause(p);
49 if p.expect(L_CURLY) { 49 if p.expect(L_CURLY) {
50 while !p.at(EOF) && !p.at(R_CURLY) { 50 while !p.at(EOF) && !p.at(R_CURLY) {
51 let var = p.start(); 51 let var = p.start();
diff --git a/src/parser/event_parser/grammar/items/use_item.rs b/src/parser/event_parser/grammar/items/use_item.rs
new file mode 100644
index 000000000..38e7b3f8a
--- /dev/null
+++ b/src/parser/event_parser/grammar/items/use_item.rs
@@ -0,0 +1,66 @@
1use super::*;
2
3pub(super) fn use_item(p: &mut Parser) {
4 assert!(p.at(USE_KW));
5 p.bump();
6 use_tree(p);
7 p.expect(SEMI);
8}
9
10fn use_tree(p: &mut Parser) {
11 let la = p.nth(1);
12 let m = p.start();
13 match (p.current(), la) {
14 (STAR, _) => p.bump(),
15 (COLONCOLON, STAR) => {
16 p.bump();
17 p.bump();
18 }
19 (L_CURLY, _) | (COLONCOLON, L_CURLY) => {
20 if p.at(COLONCOLON) {
21 p.bump();
22 }
23 nested_trees(p);
24 }
25 _ if paths::is_path_start(p) => {
26 paths::use_path(p);
27 match p.current() {
28 AS_KW => {
29 alias(p);
30 }
31 COLONCOLON => {
32 p.bump();
33 match p.current() {
34 STAR => {
35 p.bump();
36 }
37 L_CURLY => nested_trees(p),
38 _ => {
39 // is this unreachable?
40 p.error().message("expected `{` or `*`").emit();
41 }
42 }
43 }
44 _ => (),
45 }
46 }
47 _ => {
48 m.abandon(p);
49 p.err_and_bump("expected one of `*`, `::`, `{`, `self`, `super`, `indent`");
50 return;
51 }
52 }
53 m.complete(p, USE_TREE);
54}
55
56fn nested_trees(p: &mut Parser) {
57 assert!(p.at(L_CURLY));
58 p.bump();
59 while !p.at(EOF) && !p.at(R_CURLY) {
60 use_tree(p);
61 if !p.at(R_CURLY) {
62 p.expect(COMMA);
63 }
64 }
65 p.expect(R_CURLY);
66}
diff --git a/src/parser/event_parser/grammar/mod.rs b/src/parser/event_parser/grammar/mod.rs
index e7f1915d2..afce308d0 100644
--- a/src/parser/event_parser/grammar/mod.rs
+++ b/src/parser/event_parser/grammar/mod.rs
@@ -7,6 +7,7 @@ mod attributes;
7mod expressions; 7mod expressions;
8mod types; 8mod types;
9mod paths; 9mod paths;
10mod type_params;
10 11
11pub(crate) fn file(p: &mut Parser) { 12pub(crate) fn file(p: &mut Parser) {
12 let file = p.start(); 13 let file = p.start();
diff --git a/src/parser/event_parser/grammar/paths.rs b/src/parser/event_parser/grammar/paths.rs
index 4c0d2c8b4..6efac2610 100644
--- a/src/parser/event_parser/grammar/paths.rs
+++ b/src/parser/event_parser/grammar/paths.rs
@@ -20,7 +20,11 @@ fn path(p: &mut Parser) {
20 path_segment(p, true); 20 path_segment(p, true);
21 let mut qual = path.complete(p, PATH); 21 let mut qual = path.complete(p, PATH);
22 loop { 22 loop {
23 if p.at(COLONCOLON) && !items::is_use_tree_start(p.nth(1)) { 23 let use_tree = match p.nth(1) {
24 STAR | L_CURLY => true,
25 _ => false,
26 };
27 if p.at(COLONCOLON) && !use_tree {
24 let path = qual.precede(p); 28 let path = qual.precede(p);
25 p.bump(); 29 p.bump();
26 path_segment(p, false); 30 path_segment(p, false);
diff --git a/src/parser/event_parser/grammar/type_params.rs b/src/parser/event_parser/grammar/type_params.rs
new file mode 100644
index 000000000..12c9a5362
--- /dev/null
+++ b/src/parser/event_parser/grammar/type_params.rs
@@ -0,0 +1,75 @@
1use super::*;
2
3pub(super) fn list(p: &mut Parser) {
4 if !p.at(L_ANGLE) {
5 return;
6 }
7 let m = p.start();
8 p.bump();
9
10 while !p.at(EOF) && !p.at(R_ANGLE) {
11 match p.current() {
12 LIFETIME => lifetime_param(p),
13 IDENT => type_param(p),
14 _ => p.err_and_bump("expected type parameter"),
15 }
16 if !p.at(R_ANGLE) && !p.expect(COMMA) {
17 break;
18 }
19 }
20 p.expect(R_ANGLE);
21 m.complete(p, TYPE_PARAM_LIST);
22
23 fn lifetime_param(p: &mut Parser) {
24 assert!(p.at(LIFETIME));
25 let m = p.start();
26 p.bump();
27 if p.eat(COLON) {
28 while p.at(LIFETIME) {
29 p.bump();
30 if !p.eat(PLUS) {
31 break;
32 }
33 }
34 }
35 m.complete(p, LIFETIME_PARAM);
36 }
37
38 fn type_param(p: &mut Parser) {
39 assert!(p.at(IDENT));
40 let m = p.start();
41 p.bump();
42 if p.eat(COLON) {
43 loop {
44 let has_paren = p.eat(L_PAREN);
45 p.eat(QUESTION);
46 if p.at(FOR_KW) {
47 //TODO
48 }
49 if p.at(LIFETIME) {
50 p.bump();
51 } else if paths::is_path_start(p) {
52 paths::type_path(p);
53 } else {
54 break;
55 }
56 if has_paren {
57 p.expect(R_PAREN);
58 }
59 if !p.eat(PLUS) {
60 break;
61 }
62 }
63 }
64 if p.at(EQ) {
65 types::type_ref(p)
66 }
67 m.complete(p, TYPE_PARAM);
68 }
69}
70
71pub(super) fn where_clause(p: &mut Parser) {
72 if p.at(WHERE_KW) {
73 p.bump();
74 }
75}