diff options
-rw-r--r-- | src/parser/event_parser/grammar/attributes.rs | 33 | ||||
-rw-r--r-- | src/parser/event_parser/grammar/expressions.rs | 21 | ||||
-rw-r--r-- | src/parser/event_parser/grammar/items.rs | 65 | ||||
-rw-r--r-- | src/parser/event_parser/grammar/mod.rs | 15 | ||||
-rw-r--r-- | src/parser/event_parser/grammar/paths.rs | 59 |
5 files changed, 100 insertions, 93 deletions
diff --git a/src/parser/event_parser/grammar/attributes.rs b/src/parser/event_parser/grammar/attributes.rs index a896b4901..8b5e5bcfe 100644 --- a/src/parser/event_parser/grammar/attributes.rs +++ b/src/parser/event_parser/grammar/attributes.rs | |||
@@ -1,5 +1,6 @@ | |||
1 | use super::*; | 1 | use super::*; |
2 | 2 | ||
3 | #[derive(PartialEq, Eq)] | ||
3 | enum AttrKind { | 4 | enum AttrKind { |
4 | Inner, Outer | 5 | Inner, Outer |
5 | } | 6 | } |
@@ -14,18 +15,27 @@ pub(super) fn outer_attributes(p: &mut Parser) { | |||
14 | 15 | ||
15 | 16 | ||
16 | fn attribute(p: &mut Parser, kind: AttrKind) -> bool { | 17 | fn attribute(p: &mut Parser, kind: AttrKind) -> bool { |
17 | fn attr_tail(p: &mut Parser) { | 18 | if p.at(POUND) { |
18 | meta_item(p) && p.expect(R_BRACK); | 19 | if kind == AttrKind::Inner && p.raw_lookahead(1) != EXCL { |
19 | } | 20 | return false; |
20 | 21 | } | |
21 | match kind { | 22 | p.start(ATTR); |
22 | AttrKind::Inner => node_if(p, [POUND, EXCL, L_BRACK], ATTR, attr_tail), | 23 | p.bump(); |
23 | AttrKind::Outer => node_if(p, [POUND, L_BRACK], ATTR, attr_tail), | 24 | if kind == AttrKind::Inner { |
25 | p.bump(); | ||
26 | } | ||
27 | p.expect(L_BRACK) && meta_item(p) && p.expect(R_BRACK); | ||
28 | p.finish(); | ||
29 | true | ||
30 | } else { | ||
31 | false | ||
24 | } | 32 | } |
25 | } | 33 | } |
26 | 34 | ||
27 | fn meta_item(p: &mut Parser) -> bool { | 35 | fn meta_item(p: &mut Parser) -> bool { |
28 | node_if(p, IDENT, META_ITEM, |p| { | 36 | if p.at(IDENT) { |
37 | p.start(META_ITEM); | ||
38 | p.bump(); | ||
29 | if p.eat(EQ) { | 39 | if p.eat(EQ) { |
30 | if !expressions::literal(p) { | 40 | if !expressions::literal(p) { |
31 | p.error() | 41 | p.error() |
@@ -36,7 +46,12 @@ fn meta_item(p: &mut Parser) -> bool { | |||
36 | comma_list(p, R_PAREN, meta_item_inner); | 46 | comma_list(p, R_PAREN, meta_item_inner); |
37 | p.expect(R_PAREN); | 47 | p.expect(R_PAREN); |
38 | } | 48 | } |
39 | }) | 49 | p.finish(); |
50 | true | ||
51 | } else { | ||
52 | false | ||
53 | } | ||
54 | |||
40 | } | 55 | } |
41 | 56 | ||
42 | fn meta_item_inner(p: &mut Parser) -> bool { | 57 | fn meta_item_inner(p: &mut Parser) -> bool { |
diff --git a/src/parser/event_parser/grammar/expressions.rs b/src/parser/event_parser/grammar/expressions.rs index f40a3cce2..0f65193c9 100644 --- a/src/parser/event_parser/grammar/expressions.rs +++ b/src/parser/event_parser/grammar/expressions.rs | |||
@@ -1,11 +1,16 @@ | |||
1 | use super::*; | 1 | use super::*; |
2 | 2 | ||
3 | pub(super) fn literal(p: &mut Parser) -> bool { | 3 | pub(super) fn literal(p: &mut Parser) -> bool { |
4 | let literals = [ | 4 | match p.current() { |
5 | TRUE_KW, FALSE_KW, | 5 | TRUE_KW | FALSE_KW | |
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 | ]; | 9 | p.start(LITERAL); |
10 | node_if(p, AnyOf(&literals), LITERAL, |_| ()) | 10 | p.bump(); |
11 | } \ No newline at end of file | 11 | p.finish(); |
12 | true | ||
13 | } | ||
14 | _ => false | ||
15 | } | ||
16 | } | ||
diff --git a/src/parser/event_parser/grammar/items.rs b/src/parser/event_parser/grammar/items.rs index f96f4cc9c..4514f0dab 100644 --- a/src/parser/event_parser/grammar/items.rs +++ b/src/parser/event_parser/grammar/items.rs | |||
@@ -7,7 +7,7 @@ pub(super) fn mod_contents(p: &mut Parser) { | |||
7 | } | 7 | } |
8 | } | 8 | } |
9 | 9 | ||
10 | fn item(p: &mut Parser){ | 10 | fn item(p: &mut Parser) { |
11 | let attrs_start = p.mark(); | 11 | let attrs_start = p.mark(); |
12 | attributes::outer_attributes(p); | 12 | attributes::outer_attributes(p); |
13 | visibility(p); | 13 | visibility(p); |
@@ -51,7 +51,7 @@ fn struct_item(p: &mut Parser) { | |||
51 | fn struct_inner(p: &mut Parser) { | 51 | fn struct_inner(p: &mut Parser) { |
52 | if !p.expect(IDENT) { | 52 | if !p.expect(IDENT) { |
53 | p.finish(); | 53 | p.finish(); |
54 | return | 54 | return; |
55 | } | 55 | } |
56 | generic_parameters(p); | 56 | generic_parameters(p); |
57 | match p.current() { | 57 | match p.current() { |
@@ -60,31 +60,31 @@ fn struct_item(p: &mut Parser) { | |||
60 | match p.current() { | 60 | match p.current() { |
61 | SEMI => { | 61 | SEMI => { |
62 | p.bump(); | 62 | p.bump(); |
63 | return | 63 | return; |
64 | } | 64 | } |
65 | L_CURLY => named_fields(p), | 65 | L_CURLY => named_fields(p), |
66 | _ => { //TODO: special case `(` error message | 66 | _ => { //TODO: special case `(` error message |
67 | p.error() | 67 | p.error() |
68 | .message("expected `;` or `{`") | 68 | .message("expected `;` or `{`") |
69 | .emit(); | 69 | .emit(); |
70 | return | 70 | return; |
71 | } | 71 | } |
72 | } | 72 | } |
73 | } | 73 | } |
74 | SEMI => { | 74 | SEMI => { |
75 | p.bump(); | 75 | p.bump(); |
76 | return | 76 | return; |
77 | } | 77 | } |
78 | L_CURLY => named_fields(p), | 78 | L_CURLY => named_fields(p), |
79 | L_PAREN => { | 79 | L_PAREN => { |
80 | tuple_fields(p); | 80 | tuple_fields(p); |
81 | p.expect(SEMI); | 81 | p.expect(SEMI); |
82 | }, | 82 | } |
83 | _ => { | 83 | _ => { |
84 | p.error() | 84 | p.error() |
85 | .message("expected `;`, `{`, or `(`") | 85 | .message("expected `;`, `{`, or `(`") |
86 | .emit(); | 86 | .emit(); |
87 | return | 87 | return; |
88 | } | 88 | } |
89 | } | 89 | } |
90 | } | 90 | } |
@@ -108,7 +108,7 @@ fn named_fields(p: &mut Parser) { | |||
108 | 108 | ||
109 | fn tuple_fields(p: &mut Parser) { | 109 | fn tuple_fields(p: &mut Parser) { |
110 | if !p.expect(L_PAREN) { | 110 | if !p.expect(L_PAREN) { |
111 | return | 111 | return; |
112 | } | 112 | } |
113 | comma_list(p, R_PAREN, |p| { | 113 | comma_list(p, R_PAREN, |p| { |
114 | tuple_field(p); | 114 | tuple_field(p); |
@@ -124,11 +124,9 @@ fn tuple_fields(p: &mut Parser) { | |||
124 | } | 124 | } |
125 | } | 125 | } |
126 | 126 | ||
127 | fn generic_parameters(_: &mut Parser) { | 127 | fn generic_parameters(_: &mut Parser) {} |
128 | } | ||
129 | 128 | ||
130 | fn where_clause(_: &mut Parser) { | 129 | fn where_clause(_: &mut Parser) {} |
131 | } | ||
132 | 130 | ||
133 | fn extern_crate_item(p: &mut Parser) { | 131 | fn extern_crate_item(p: &mut Parser) { |
134 | p.start(EXTERN_CRATE_ITEM); | 132 | p.start(EXTERN_CRATE_ITEM); |
@@ -168,24 +166,29 @@ fn use_item(p: &mut Parser) { | |||
168 | p.expect(SEMI); | 166 | p.expect(SEMI); |
169 | p.finish(); | 167 | p.finish(); |
170 | 168 | ||
171 | fn use_tree(p: &mut Parser) -> bool{ | 169 | fn use_tree(p: &mut Parser) -> bool { |
172 | if node_if(p, STAR, USE_TREE, |_| ()) { | 170 | let la = p.raw_lookahead(1); |
173 | return true | 171 | match (p.current(), la) { |
174 | } | 172 | (STAR, _) => { |
175 | if node_if(p, [COLONCOLON, STAR], USE_TREE, |_| ()) { | 173 | p.start(USE_TREE); |
176 | return true | 174 | p.bump(); |
177 | } | 175 | } |
178 | if [COLONCOLON, L_CURLY].is_ahead(p) || L_CURLY.is_ahead(p) { | 176 | (COLONCOLON, STAR) => { |
179 | node(p, USE_TREE, |p| { | 177 | p.start(USE_TREE); |
180 | p.eat(COLONCOLON); | 178 | p.bump(); |
179 | p.bump(); | ||
180 | } | ||
181 | (L_CURLY, _) | (COLONCOLON, L_CURLY) => { | ||
182 | p.start(USE_TREE); | ||
183 | if p.at(COLONCOLON) { | ||
184 | p.bump(); | ||
185 | } | ||
181 | p.curly_block(|p| { | 186 | p.curly_block(|p| { |
182 | comma_list(p, EOF, use_tree); | 187 | comma_list(p, EOF, use_tree); |
183 | }); | 188 | }); |
184 | }); | 189 | } |
185 | return true; | 190 | _ if paths::is_path_start(p) => { |
186 | } | 191 | p.start(USE_TREE); |
187 | if paths::is_path_start(p) { | ||
188 | node(p, USE_TREE, |p| { | ||
189 | paths::use_path(p); | 192 | paths::use_path(p); |
190 | match p.current() { | 193 | match p.current() { |
191 | AS_KW => { | 194 | AS_KW => { |
@@ -212,15 +215,15 @@ fn use_item(p: &mut Parser) { | |||
212 | } | 215 | } |
213 | _ => (), | 216 | _ => (), |
214 | } | 217 | } |
215 | }); | 218 | } |
216 | return true; | 219 | _ => return false, |
217 | } | 220 | } |
218 | false | 221 | p.finish(); |
222 | return true; | ||
219 | } | 223 | } |
220 | } | 224 | } |
221 | 225 | ||
222 | 226 | ||
223 | |||
224 | fn fn_item(p: &mut Parser) { | 227 | fn fn_item(p: &mut Parser) { |
225 | p.start(FN_ITEM); | 228 | p.start(FN_ITEM); |
226 | 229 | ||
diff --git a/src/parser/event_parser/grammar/mod.rs b/src/parser/event_parser/grammar/mod.rs index 0c775bb25..c3d0c8c10 100644 --- a/src/parser/event_parser/grammar/mod.rs +++ b/src/parser/event_parser/grammar/mod.rs | |||
@@ -46,21 +46,6 @@ fn alias(p: &mut Parser) -> bool { | |||
46 | true //FIXME: return false if three are errors | 46 | true //FIXME: return false if three are errors |
47 | } | 47 | } |
48 | 48 | ||
49 | fn node_if<F: FnOnce(&mut Parser), L: Lookahead>( | ||
50 | p: &mut Parser, | ||
51 | first: L, | ||
52 | node_kind: SyntaxKind, | ||
53 | rest: F | ||
54 | ) -> bool { | ||
55 | first.is_ahead(p) && { node(p, node_kind, |p| { L::consume(p); rest(p); }); true } | ||
56 | } | ||
57 | |||
58 | fn node<F: FnOnce(&mut Parser)>(p: &mut Parser, node_kind: SyntaxKind, rest: F) { | ||
59 | p.start(node_kind); | ||
60 | rest(p); | ||
61 | p.finish(); | ||
62 | } | ||
63 | |||
64 | fn repeat<F: FnMut(&mut Parser) -> bool>(p: &mut Parser, mut f: F) { | 49 | fn repeat<F: FnMut(&mut Parser) -> bool>(p: &mut Parser, mut f: F) { |
65 | loop { | 50 | loop { |
66 | let pos = p.pos(); | 51 | let pos = p.pos(); |
diff --git a/src/parser/event_parser/grammar/paths.rs b/src/parser/event_parser/grammar/paths.rs index 45f3cb779..f5124cfce 100644 --- a/src/parser/event_parser/grammar/paths.rs +++ b/src/parser/event_parser/grammar/paths.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use super::*; | 1 | use super::*; |
2 | 2 | ||
3 | pub (crate) fn is_path_start(p: &Parser) -> bool { | 3 | pub(crate) fn is_path_start(p: &Parser) -> bool { |
4 | AnyOf(&[IDENT, SELF_KW, SUPER_KW, COLONCOLON]).is_ahead(p) | 4 | AnyOf(&[IDENT, SELF_KW, SUPER_KW, COLONCOLON]).is_ahead(p) |
5 | } | 5 | } |
6 | 6 | ||
@@ -9,39 +9,38 @@ pub(crate) fn use_path(p: &mut Parser) { | |||
9 | return; | 9 | return; |
10 | } | 10 | } |
11 | let mut prev = p.mark(); | 11 | let mut prev = p.mark(); |
12 | node(p, PATH, |p| { | 12 | p.start(PATH); |
13 | path_segment(p, true); | 13 | path_segment(p, true); |
14 | }); | 14 | p.finish(); |
15 | repeat(p, |p| { | 15 | loop { |
16 | let curr = p.mark(); | 16 | let curr = p.mark(); |
17 | if p.current() == COLONCOLON && !items::is_use_tree_start(p.raw_lookahead(1)) { | 17 | if p.at(COLONCOLON) && !items::is_use_tree_start(p.raw_lookahead(1)) { |
18 | node(p, PATH, |p| { | 18 | p.start(PATH); |
19 | p.bump(); | 19 | p.bump(); |
20 | path_segment(p, false); | 20 | path_segment(p, false); |
21 | p.forward_parent(prev, curr); | 21 | p.forward_parent(prev, curr); |
22 | prev = curr; | 22 | prev = curr; |
23 | }); | 23 | p.finish(); |
24 | true | ||
25 | } else { | 24 | } else { |
26 | false | 25 | break; |
27 | } | 26 | } |
28 | }); | 27 | } |
29 | } | 28 | } |
30 | 29 | ||
31 | fn path_segment(p: &mut Parser, first: bool) { | 30 | fn path_segment(p: &mut Parser, first: bool) { |
32 | node(p, PATH_SEGMENT, |p| { | 31 | p.start(PATH_SEGMENT); |
33 | if first { | 32 | if first { |
34 | p.eat(COLONCOLON); | 33 | p.eat(COLONCOLON); |
34 | } | ||
35 | match p.current() { | ||
36 | IDENT | SELF_KW | SUPER_KW => { | ||
37 | p.bump(); | ||
35 | } | 38 | } |
36 | match p.current() { | 39 | _ => { |
37 | IDENT | SELF_KW | SUPER_KW => { | 40 | p.error() |
38 | p.bump(); | 41 | .message("expected identifier") |
39 | }, | 42 | .emit(); |
40 | _ => { | 43 | } |
41 | p.error() | 44 | }; |
42 | .message("expected identifier") | 45 | p.finish(); |
43 | .emit(); | 46 | } |
44 | } | ||
45 | }; | ||
46 | }) | ||
47 | } \ No newline at end of file | ||