diff options
author | Aleksey Kladov <[email protected]> | 2018-01-20 20:25:34 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-01-20 20:25:34 +0000 |
commit | 0b5d39f2a204e5ec6cd6205440e4cdc763162814 (patch) | |
tree | 8d201ef62b5e4fe48e3cce7b557071e434530801 /src/parser/event_parser/grammar/items.rs | |
parent | be60d5aa6669a74e92495288f44b7f9258a8518f (diff) |
Markers API
Diffstat (limited to 'src/parser/event_parser/grammar/items.rs')
-rw-r--r-- | src/parser/event_parser/grammar/items.rs | 151 |
1 files changed, 73 insertions, 78 deletions
diff --git a/src/parser/event_parser/grammar/items.rs b/src/parser/event_parser/grammar/items.rs index 4514f0dab..c9a890553 100644 --- a/src/parser/event_parser/grammar/items.rs +++ b/src/parser/event_parser/grammar/items.rs | |||
@@ -8,19 +8,34 @@ pub(super) fn mod_contents(p: &mut Parser) { | |||
8 | } | 8 | } |
9 | 9 | ||
10 | fn item(p: &mut Parser) { | 10 | fn item(p: &mut Parser) { |
11 | let attrs_start = p.mark(); | 11 | let item = p.start(); |
12 | attributes::outer_attributes(p); | 12 | attributes::outer_attributes(p); |
13 | visibility(p); | 13 | visibility(p); |
14 | let la = p.raw_lookahead(1); | 14 | let la = p.raw_lookahead(1); |
15 | let item_start = p.mark(); | 15 | let item_kind = match p.current() { |
16 | match p.current() { | 16 | EXTERN_KW if la == CRATE_KW => { |
17 | EXTERN_KW if la == CRATE_KW => extern_crate_item(p), | 17 | extern_crate_item(p); |
18 | MOD_KW => mod_item(p), | 18 | EXTERN_CRATE_ITEM |
19 | USE_KW => use_item(p), | 19 | } |
20 | STRUCT_KW => struct_item(p), | 20 | MOD_KW => { |
21 | FN_KW => fn_item(p), | 21 | mod_item(p); |
22 | MOD_ITEM | ||
23 | } | ||
24 | USE_KW => { | ||
25 | use_item(p); | ||
26 | USE_ITEM | ||
27 | } | ||
28 | STRUCT_KW => { | ||
29 | struct_item(p); | ||
30 | STRUCT_ITEM | ||
31 | } | ||
32 | FN_KW => { | ||
33 | fn_item(p); | ||
34 | FN_ITEM | ||
35 | } | ||
22 | err_token => { | 36 | err_token => { |
23 | p.start(ERROR); | 37 | item.abandon(p); |
38 | let err = p.start(); | ||
24 | let message = if err_token == SEMI { | 39 | let message = if err_token == SEMI { |
25 | //TODO: if the item is incomplete, this message is misleading | 40 | //TODO: if the item is incomplete, this message is misleading |
26 | "expected item, found `;`\n\ | 41 | "expected item, found `;`\n\ |
@@ -32,60 +47,52 @@ fn item(p: &mut Parser) { | |||
32 | .message(message) | 47 | .message(message) |
33 | .emit(); | 48 | .emit(); |
34 | p.bump(); | 49 | p.bump(); |
35 | p.finish(); | 50 | err.complete(p, ERROR); |
36 | return; | 51 | return; |
37 | } | 52 | } |
38 | }; | 53 | }; |
39 | p.forward_parent(attrs_start, item_start); | 54 | item.complete(p, item_kind); |
40 | } | 55 | } |
41 | 56 | ||
42 | fn struct_item(p: &mut Parser) { | 57 | fn struct_item(p: &mut Parser) { |
43 | p.start(STRUCT_ITEM); | ||
44 | |||
45 | assert!(p.at(STRUCT_KW)); | 58 | assert!(p.at(STRUCT_KW)); |
46 | p.bump(); | 59 | p.bump(); |
47 | 60 | ||
48 | struct_inner(p); | 61 | if !p.expect(IDENT) { |
49 | p.finish(); | 62 | return; |
50 | 63 | } | |
51 | fn struct_inner(p: &mut Parser) { | 64 | generic_parameters(p); |
52 | if !p.expect(IDENT) { | 65 | match p.current() { |
53 | p.finish(); | 66 | WHERE_KW => { |
54 | return; | 67 | where_clause(p); |
55 | } | 68 | match p.current() { |
56 | generic_parameters(p); | 69 | SEMI => { |
57 | match p.current() { | 70 | p.bump(); |
58 | WHERE_KW => { | 71 | return; |
59 | where_clause(p); | 72 | } |
60 | match p.current() { | 73 | L_CURLY => named_fields(p), |
61 | SEMI => { | 74 | _ => { //TODO: special case `(` error message |
62 | p.bump(); | 75 | p.error() |
63 | return; | 76 | .message("expected `;` or `{`") |
64 | } | 77 | .emit(); |
65 | L_CURLY => named_fields(p), | 78 | return; |
66 | _ => { //TODO: special case `(` error message | ||
67 | p.error() | ||
68 | .message("expected `;` or `{`") | ||
69 | .emit(); | ||
70 | return; | ||
71 | } | ||
72 | } | 79 | } |
73 | } | 80 | } |
74 | SEMI => { | 81 | } |
75 | p.bump(); | 82 | SEMI => { |
76 | return; | 83 | p.bump(); |
77 | } | 84 | return; |
78 | L_CURLY => named_fields(p), | 85 | } |
79 | L_PAREN => { | 86 | L_CURLY => named_fields(p), |
80 | tuple_fields(p); | 87 | L_PAREN => { |
81 | p.expect(SEMI); | 88 | pos_fields(p); |
82 | } | 89 | p.expect(SEMI); |
83 | _ => { | 90 | } |
84 | p.error() | 91 | _ => { |
85 | .message("expected `;`, `{`, or `(`") | 92 | p.error() |
86 | .emit(); | 93 | .message("expected `;`, `{`, or `(`") |
87 | return; | 94 | .emit(); |
88 | } | 95 | return; |
89 | } | 96 | } |
90 | } | 97 | } |
91 | } | 98 | } |
@@ -97,30 +104,30 @@ fn named_fields(p: &mut Parser) { | |||
97 | })); | 104 | })); |
98 | 105 | ||
99 | fn named_field(p: &mut Parser) { | 106 | fn named_field(p: &mut Parser) { |
100 | p.start(NAMED_FIELD); | 107 | let field = p.start(); |
101 | visibility(p); | 108 | visibility(p); |
102 | if p.expect(IDENT) && p.expect(COLON) { | 109 | if p.expect(IDENT) && p.expect(COLON) { |
103 | types::type_ref(p); | 110 | types::type_ref(p); |
104 | }; | 111 | }; |
105 | p.finish() | 112 | field.complete(p, NAMED_FIELD); |
106 | } | 113 | } |
107 | } | 114 | } |
108 | 115 | ||
109 | fn tuple_fields(p: &mut Parser) { | 116 | fn pos_fields(p: &mut Parser) { |
110 | if !p.expect(L_PAREN) { | 117 | if !p.expect(L_PAREN) { |
111 | return; | 118 | return; |
112 | } | 119 | } |
113 | comma_list(p, R_PAREN, |p| { | 120 | comma_list(p, R_PAREN, |p| { |
114 | tuple_field(p); | 121 | pos_field(p); |
115 | true | 122 | true |
116 | }); | 123 | }); |
117 | p.expect(R_PAREN); | 124 | p.expect(R_PAREN); |
118 | 125 | ||
119 | fn tuple_field(p: &mut Parser) { | 126 | fn pos_field(p: &mut Parser) { |
120 | p.start(POS_FIELD); | 127 | let pos_field = p.start(); |
121 | visibility(p); | 128 | visibility(p); |
122 | types::type_ref(p); | 129 | types::type_ref(p); |
123 | p.finish(); | 130 | pos_field.complete(p, POS_FIELD); |
124 | } | 131 | } |
125 | } | 132 | } |
126 | 133 | ||
@@ -129,28 +136,21 @@ fn generic_parameters(_: &mut Parser) {} | |||
129 | fn where_clause(_: &mut Parser) {} | 136 | fn where_clause(_: &mut Parser) {} |
130 | 137 | ||
131 | fn extern_crate_item(p: &mut Parser) { | 138 | fn extern_crate_item(p: &mut Parser) { |
132 | p.start(EXTERN_CRATE_ITEM); | ||
133 | |||
134 | assert!(p.at(EXTERN_KW)); | 139 | assert!(p.at(EXTERN_KW)); |
135 | p.bump(); | 140 | p.bump(); |
136 | |||
137 | assert!(p.at(CRATE_KW)); | 141 | assert!(p.at(CRATE_KW)); |
138 | p.bump(); | 142 | p.bump(); |
139 | 143 | ||
140 | p.expect(IDENT) && alias(p) && p.expect(SEMI); | 144 | p.expect(IDENT) && alias(p) && p.expect(SEMI); |
141 | p.finish(); | ||
142 | } | 145 | } |
143 | 146 | ||
144 | fn mod_item(p: &mut Parser) { | 147 | fn mod_item(p: &mut Parser) { |
145 | p.start(MOD_ITEM); | ||
146 | |||
147 | assert!(p.at(MOD_KW)); | 148 | assert!(p.at(MOD_KW)); |
148 | p.bump(); | 149 | p.bump(); |
149 | 150 | ||
150 | if p.expect(IDENT) && !p.eat(SEMI) { | 151 | if p.expect(IDENT) && !p.eat(SEMI) { |
151 | p.curly_block(mod_contents); | 152 | p.curly_block(mod_contents); |
152 | } | 153 | } |
153 | p.finish() | ||
154 | } | 154 | } |
155 | 155 | ||
156 | pub(super) fn is_use_tree_start(kind: SyntaxKind) -> bool { | 156 | pub(super) fn is_use_tree_start(kind: SyntaxKind) -> bool { |
@@ -158,28 +158,24 @@ pub(super) fn is_use_tree_start(kind: SyntaxKind) -> bool { | |||
158 | } | 158 | } |
159 | 159 | ||
160 | fn use_item(p: &mut Parser) { | 160 | fn use_item(p: &mut Parser) { |
161 | p.start(USE_ITEM); | ||
162 | |||
163 | assert!(p.at(USE_KW)); | 161 | assert!(p.at(USE_KW)); |
164 | p.bump(); | 162 | p.bump(); |
163 | |||
165 | use_tree(p); | 164 | use_tree(p); |
166 | p.expect(SEMI); | 165 | p.expect(SEMI); |
167 | p.finish(); | ||
168 | 166 | ||
169 | fn use_tree(p: &mut Parser) -> bool { | 167 | fn use_tree(p: &mut Parser) -> bool { |
170 | let la = p.raw_lookahead(1); | 168 | let la = p.raw_lookahead(1); |
169 | let m = p.start(); | ||
171 | match (p.current(), la) { | 170 | match (p.current(), la) { |
172 | (STAR, _) => { | 171 | (STAR, _) => { |
173 | p.start(USE_TREE); | ||
174 | p.bump(); | 172 | p.bump(); |
175 | } | 173 | } |
176 | (COLONCOLON, STAR) => { | 174 | (COLONCOLON, STAR) => { |
177 | p.start(USE_TREE); | ||
178 | p.bump(); | 175 | p.bump(); |
179 | p.bump(); | 176 | p.bump(); |
180 | } | 177 | } |
181 | (L_CURLY, _) | (COLONCOLON, L_CURLY) => { | 178 | (L_CURLY, _) | (COLONCOLON, L_CURLY) => { |
182 | p.start(USE_TREE); | ||
183 | if p.at(COLONCOLON) { | 179 | if p.at(COLONCOLON) { |
184 | p.bump(); | 180 | p.bump(); |
185 | } | 181 | } |
@@ -188,7 +184,6 @@ fn use_item(p: &mut Parser) { | |||
188 | }); | 184 | }); |
189 | } | 185 | } |
190 | _ if paths::is_path_start(p) => { | 186 | _ if paths::is_path_start(p) => { |
191 | p.start(USE_TREE); | ||
192 | paths::use_path(p); | 187 | paths::use_path(p); |
193 | match p.current() { | 188 | match p.current() { |
194 | AS_KW => { | 189 | AS_KW => { |
@@ -216,23 +211,23 @@ fn use_item(p: &mut Parser) { | |||
216 | _ => (), | 211 | _ => (), |
217 | } | 212 | } |
218 | } | 213 | } |
219 | _ => return false, | 214 | _ => { |
215 | m.abandon(p); | ||
216 | return false | ||
217 | }, | ||
220 | } | 218 | } |
221 | p.finish(); | 219 | m.complete(p, USE_TREE); |
222 | return true; | 220 | return true; |
223 | } | 221 | } |
224 | } | 222 | } |
225 | 223 | ||
226 | 224 | ||
227 | fn fn_item(p: &mut Parser) { | 225 | fn fn_item(p: &mut Parser) { |
228 | p.start(FN_ITEM); | ||
229 | |||
230 | assert!(p.at(FN_KW)); | 226 | assert!(p.at(FN_KW)); |
231 | p.bump(); | 227 | p.bump(); |
232 | 228 | ||
233 | p.expect(IDENT) && p.expect(L_PAREN) && p.expect(R_PAREN) | 229 | p.expect(IDENT) && p.expect(L_PAREN) && p.expect(R_PAREN) |
234 | && p.curly_block(|_| ()); | 230 | && p.curly_block(|_| ()); |
235 | p.finish(); | ||
236 | } | 231 | } |
237 | 232 | ||
238 | 233 | ||