diff options
Diffstat (limited to 'src/parser/event_parser/grammar')
-rw-r--r-- | src/parser/event_parser/grammar/attributes.rs | 8 | ||||
-rw-r--r-- | src/parser/event_parser/grammar/expressions.rs | 4 | ||||
-rw-r--r-- | src/parser/event_parser/grammar/items.rs | 151 | ||||
-rw-r--r-- | src/parser/event_parser/grammar/mod.rs | 12 | ||||
-rw-r--r-- | src/parser/event_parser/grammar/paths.rs | 17 |
5 files changed, 92 insertions, 100 deletions
diff --git a/src/parser/event_parser/grammar/attributes.rs b/src/parser/event_parser/grammar/attributes.rs index 8b5e5bcfe..2d04a1a41 100644 --- a/src/parser/event_parser/grammar/attributes.rs +++ b/src/parser/event_parser/grammar/attributes.rs | |||
@@ -19,13 +19,13 @@ fn attribute(p: &mut Parser, kind: AttrKind) -> bool { | |||
19 | if kind == AttrKind::Inner && p.raw_lookahead(1) != EXCL { | 19 | if kind == AttrKind::Inner && p.raw_lookahead(1) != EXCL { |
20 | return false; | 20 | return false; |
21 | } | 21 | } |
22 | p.start(ATTR); | 22 | let attr = p.start(); |
23 | p.bump(); | 23 | p.bump(); |
24 | if kind == AttrKind::Inner { | 24 | if kind == AttrKind::Inner { |
25 | p.bump(); | 25 | p.bump(); |
26 | } | 26 | } |
27 | p.expect(L_BRACK) && meta_item(p) && p.expect(R_BRACK); | 27 | p.expect(L_BRACK) && meta_item(p) && p.expect(R_BRACK); |
28 | p.finish(); | 28 | attr.complete(p, ATTR); |
29 | true | 29 | true |
30 | } else { | 30 | } else { |
31 | false | 31 | false |
@@ -34,7 +34,7 @@ fn attribute(p: &mut Parser, kind: AttrKind) -> bool { | |||
34 | 34 | ||
35 | fn meta_item(p: &mut Parser) -> bool { | 35 | fn meta_item(p: &mut Parser) -> bool { |
36 | if p.at(IDENT) { | 36 | if p.at(IDENT) { |
37 | p.start(META_ITEM); | 37 | let meta_item = p.start(); |
38 | p.bump(); | 38 | p.bump(); |
39 | if p.eat(EQ) { | 39 | if p.eat(EQ) { |
40 | if !expressions::literal(p) { | 40 | if !expressions::literal(p) { |
@@ -46,7 +46,7 @@ fn meta_item(p: &mut Parser) -> bool { | |||
46 | comma_list(p, R_PAREN, meta_item_inner); | 46 | comma_list(p, R_PAREN, meta_item_inner); |
47 | p.expect(R_PAREN); | 47 | p.expect(R_PAREN); |
48 | } | 48 | } |
49 | p.finish(); | 49 | meta_item.complete(p, META_ITEM); |
50 | true | 50 | true |
51 | } else { | 51 | } else { |
52 | false | 52 | false |
diff --git a/src/parser/event_parser/grammar/expressions.rs b/src/parser/event_parser/grammar/expressions.rs index 0f65193c9..a943b8c81 100644 --- a/src/parser/event_parser/grammar/expressions.rs +++ b/src/parser/event_parser/grammar/expressions.rs | |||
@@ -6,9 +6,9 @@ pub(super) fn literal(p: &mut Parser) -> bool { | |||
6 | INT_NUMBER | FLOAT_NUMBER | | 6 | INT_NUMBER | FLOAT_NUMBER | |
7 | BYTE | CHAR | | 7 | BYTE | CHAR | |
8 | STRING | RAW_STRING | BYTE_STRING | RAW_BYTE_STRING => { | 8 | STRING | RAW_STRING | BYTE_STRING | RAW_BYTE_STRING => { |
9 | p.start(LITERAL); | 9 | let lit = p.start(); |
10 | p.bump(); | 10 | p.bump(); |
11 | p.finish(); | 11 | lit.complete(p, LITERAL); |
12 | true | 12 | true |
13 | } | 13 | } |
14 | _ => false | 14 | _ => false |
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 | ||
diff --git a/src/parser/event_parser/grammar/mod.rs b/src/parser/event_parser/grammar/mod.rs index c3d0c8c10..d3b63c4c1 100644 --- a/src/parser/event_parser/grammar/mod.rs +++ b/src/parser/event_parser/grammar/mod.rs | |||
@@ -10,15 +10,15 @@ mod types; | |||
10 | mod paths; | 10 | mod paths; |
11 | 11 | ||
12 | pub(crate) fn file(p: &mut Parser) { | 12 | pub(crate) fn file(p: &mut Parser) { |
13 | p.start(FILE); | 13 | let file = p.start(); |
14 | p.eat(SHEBANG); | 14 | p.eat(SHEBANG); |
15 | items::mod_contents(p); | 15 | items::mod_contents(p); |
16 | p.finish() | 16 | file.complete(p, FILE); |
17 | } | 17 | } |
18 | 18 | ||
19 | fn visibility(p: &mut Parser) { | 19 | fn visibility(p: &mut Parser) { |
20 | if p.at(PUB_KW) { | 20 | if p.at(PUB_KW) { |
21 | p.start(VISIBILITY); | 21 | let vis = p.start(); |
22 | p.bump(); | 22 | p.bump(); |
23 | if p.at(L_PAREN) { | 23 | if p.at(L_PAREN) { |
24 | match p.raw_lookahead(1) { | 24 | match p.raw_lookahead(1) { |
@@ -32,16 +32,16 @@ fn visibility(p: &mut Parser) { | |||
32 | _ => () | 32 | _ => () |
33 | } | 33 | } |
34 | } | 34 | } |
35 | p.finish(); | 35 | vis.complete(p, VISIBILITY); |
36 | } | 36 | } |
37 | } | 37 | } |
38 | 38 | ||
39 | fn alias(p: &mut Parser) -> bool { | 39 | fn alias(p: &mut Parser) -> bool { |
40 | if p.at(AS_KW) { | 40 | if p.at(AS_KW) { |
41 | p.start(ALIAS); | 41 | let alias = p.start(); |
42 | p.bump(); | 42 | p.bump(); |
43 | p.expect(IDENT); | 43 | p.expect(IDENT); |
44 | p.finish(); | 44 | alias.complete(p, ALIAS); |
45 | } | 45 | } |
46 | true //FIXME: return false if three are errors | 46 | true //FIXME: return false if three are errors |
47 | } | 47 | } |
diff --git a/src/parser/event_parser/grammar/paths.rs b/src/parser/event_parser/grammar/paths.rs index f5124cfce..b58c59aef 100644 --- a/src/parser/event_parser/grammar/paths.rs +++ b/src/parser/event_parser/grammar/paths.rs | |||
@@ -8,19 +8,16 @@ pub(crate) fn use_path(p: &mut Parser) { | |||
8 | if !is_path_start(p) { | 8 | if !is_path_start(p) { |
9 | return; | 9 | return; |
10 | } | 10 | } |
11 | let mut prev = p.mark(); | 11 | let path = p.start(); |
12 | p.start(PATH); | ||
13 | path_segment(p, true); | 12 | path_segment(p, true); |
14 | p.finish(); | 13 | let mut qual = path.complete(p, PATH); |
15 | loop { | 14 | loop { |
16 | let curr = p.mark(); | ||
17 | if p.at(COLONCOLON) && !items::is_use_tree_start(p.raw_lookahead(1)) { | 15 | if p.at(COLONCOLON) && !items::is_use_tree_start(p.raw_lookahead(1)) { |
18 | p.start(PATH); | 16 | let path = qual.precede(p); |
19 | p.bump(); | 17 | p.bump(); |
20 | path_segment(p, false); | 18 | path_segment(p, false); |
21 | p.forward_parent(prev, curr); | 19 | let path = path.complete(p, PATH); |
22 | prev = curr; | 20 | qual = path; |
23 | p.finish(); | ||
24 | } else { | 21 | } else { |
25 | break; | 22 | break; |
26 | } | 23 | } |
@@ -28,7 +25,7 @@ pub(crate) fn use_path(p: &mut Parser) { | |||
28 | } | 25 | } |
29 | 26 | ||
30 | fn path_segment(p: &mut Parser, first: bool) { | 27 | fn path_segment(p: &mut Parser, first: bool) { |
31 | p.start(PATH_SEGMENT); | 28 | let segment = p.start(); |
32 | if first { | 29 | if first { |
33 | p.eat(COLONCOLON); | 30 | p.eat(COLONCOLON); |
34 | } | 31 | } |
@@ -42,5 +39,5 @@ fn path_segment(p: &mut Parser, first: bool) { | |||
42 | .emit(); | 39 | .emit(); |
43 | } | 40 | } |
44 | }; | 41 | }; |
45 | p.finish(); | 42 | segment.complete(p, PATH_SEGMENT); |
46 | } | 43 | } |