diff options
-rw-r--r-- | grammar.ron | 5 | ||||
-rw-r--r-- | src/parser/event_parser/grammar/items/mod.rs | 26 | ||||
-rw-r--r-- | src/parser/event_parser/grammar/paths.rs | 13 | ||||
-rw-r--r-- | src/syntax_kinds.rs | 15 | ||||
-rw-r--r-- | tests/data/lexer/0011_keywords.rs | 2 | ||||
-rw-r--r-- | tests/data/lexer/0011_keywords.txt | 10 | ||||
-rw-r--r-- | tests/data/parser/err/0001_item_recovery_in_file.txt | 4 | ||||
-rw-r--r-- | tests/data/parser/err/0008_item_block_recovery.txt | 2 | ||||
-rw-r--r-- | tests/data/parser/ok/0020_type_param_bounds.rs | 9 | ||||
-rw-r--r-- | tests/data/parser/ok/0020_type_param_bounds.txt | 169 |
10 files changed, 248 insertions, 7 deletions
diff --git a/grammar.ron b/grammar.ron index d7fea44fb..8585fd2d4 100644 --- a/grammar.ron +++ b/grammar.ron | |||
@@ -17,6 +17,11 @@ Grammar( | |||
17 | "super", | 17 | "super", |
18 | "in", | 18 | "in", |
19 | "where", | 19 | "where", |
20 | "for", | ||
21 | "loop", | ||
22 | "while", | ||
23 | "if", | ||
24 | "match" | ||
20 | ], | 25 | ], |
21 | tokens: [ | 26 | tokens: [ |
22 | "ERROR", | 27 | "ERROR", |
diff --git a/src/parser/event_parser/grammar/items/mod.rs b/src/parser/event_parser/grammar/items/mod.rs index 0a50fffc1..4d8783735 100644 --- a/src/parser/event_parser/grammar/items/mod.rs +++ b/src/parser/event_parser/grammar/items/mod.rs | |||
@@ -103,8 +103,32 @@ fn type_param_list(p: &mut Parser) { | |||
103 | assert!(p.at(IDENT)); | 103 | assert!(p.at(IDENT)); |
104 | let m = p.start(); | 104 | let m = p.start(); |
105 | p.bump(); | 105 | p.bump(); |
106 | if p.eat(COLON) { | ||
107 | loop { | ||
108 | let has_paren = p.eat(L_PAREN); | ||
109 | p.eat(QUESTION); | ||
110 | if p.at(FOR_KW) { | ||
111 | //TODO | ||
112 | } | ||
113 | if p.at(LIFETIME) { | ||
114 | p.bump(); | ||
115 | } else if paths::is_path_start(p) { | ||
116 | paths::type_path(p); | ||
117 | } else { | ||
118 | break; | ||
119 | } | ||
120 | if has_paren { | ||
121 | p.expect(R_PAREN); | ||
122 | } | ||
123 | if !p.eat(PLUS) { | ||
124 | break; | ||
125 | } | ||
126 | } | ||
127 | } | ||
128 | if p.at(EQ) { | ||
129 | types::type_ref(p) | ||
130 | } | ||
106 | m.complete(p, TYPE_PARAM); | 131 | m.complete(p, TYPE_PARAM); |
107 | //TODO: bounds | ||
108 | } | 132 | } |
109 | } | 133 | } |
110 | 134 | ||
diff --git a/src/parser/event_parser/grammar/paths.rs b/src/parser/event_parser/grammar/paths.rs index a254ab05e..bf3c8aedd 100644 --- a/src/parser/event_parser/grammar/paths.rs +++ b/src/parser/event_parser/grammar/paths.rs | |||
@@ -1,10 +1,18 @@ | |||
1 | use super::*; | 1 | use super::*; |
2 | 2 | ||
3 | pub(crate) fn is_path_start(p: &Parser) -> bool { | 3 | pub(super) 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 | ||
7 | pub(crate) fn use_path(p: &mut Parser) { | 7 | pub(super) fn use_path(p: &mut Parser) { |
8 | path(p) | ||
9 | } | ||
10 | |||
11 | pub(super) fn type_path(p: &mut Parser) { | ||
12 | path(p) | ||
13 | } | ||
14 | |||
15 | fn path(p: &mut Parser) { | ||
8 | if !is_path_start(p) { | 16 | if !is_path_start(p) { |
9 | return; | 17 | return; |
10 | } | 18 | } |
@@ -24,6 +32,7 @@ pub(crate) fn use_path(p: &mut Parser) { | |||
24 | } | 32 | } |
25 | } | 33 | } |
26 | 34 | ||
35 | |||
27 | fn path_segment(p: &mut Parser, first: bool) { | 36 | fn path_segment(p: &mut Parser, first: bool) { |
28 | let segment = p.start(); | 37 | let segment = p.start(); |
29 | if first { | 38 | if first { |
diff --git a/src/syntax_kinds.rs b/src/syntax_kinds.rs index 519326f48..cd4c753a9 100644 --- a/src/syntax_kinds.rs +++ b/src/syntax_kinds.rs | |||
@@ -23,6 +23,11 @@ pub enum SyntaxKind { | |||
23 | SUPER_KW, | 23 | SUPER_KW, |
24 | IN_KW, | 24 | IN_KW, |
25 | WHERE_KW, | 25 | WHERE_KW, |
26 | FOR_KW, | ||
27 | LOOP_KW, | ||
28 | WHILE_KW, | ||
29 | IF_KW, | ||
30 | MATCH_KW, | ||
26 | ERROR, | 31 | ERROR, |
27 | IDENT, | 32 | IDENT, |
28 | UNDERSCORE, | 33 | UNDERSCORE, |
@@ -125,6 +130,11 @@ impl SyntaxKind { | |||
125 | SUPER_KW => &SyntaxInfo { name: "SUPER_KW" }, | 130 | SUPER_KW => &SyntaxInfo { name: "SUPER_KW" }, |
126 | IN_KW => &SyntaxInfo { name: "IN_KW" }, | 131 | IN_KW => &SyntaxInfo { name: "IN_KW" }, |
127 | WHERE_KW => &SyntaxInfo { name: "WHERE_KW" }, | 132 | WHERE_KW => &SyntaxInfo { name: "WHERE_KW" }, |
133 | FOR_KW => &SyntaxInfo { name: "FOR_KW" }, | ||
134 | LOOP_KW => &SyntaxInfo { name: "LOOP_KW" }, | ||
135 | WHILE_KW => &SyntaxInfo { name: "WHILE_KW" }, | ||
136 | IF_KW => &SyntaxInfo { name: "IF_KW" }, | ||
137 | MATCH_KW => &SyntaxInfo { name: "MATCH_KW" }, | ||
128 | ERROR => &SyntaxInfo { name: "ERROR" }, | 138 | ERROR => &SyntaxInfo { name: "ERROR" }, |
129 | IDENT => &SyntaxInfo { name: "IDENT" }, | 139 | IDENT => &SyntaxInfo { name: "IDENT" }, |
130 | UNDERSCORE => &SyntaxInfo { name: "UNDERSCORE" }, | 140 | UNDERSCORE => &SyntaxInfo { name: "UNDERSCORE" }, |
@@ -223,6 +233,11 @@ pub(crate) fn ident_to_keyword(ident: &str) -> Option<SyntaxKind> { | |||
223 | "super" => Some(SUPER_KW), | 233 | "super" => Some(SUPER_KW), |
224 | "in" => Some(IN_KW), | 234 | "in" => Some(IN_KW), |
225 | "where" => Some(WHERE_KW), | 235 | "where" => Some(WHERE_KW), |
236 | "for" => Some(FOR_KW), | ||
237 | "loop" => Some(LOOP_KW), | ||
238 | "while" => Some(WHILE_KW), | ||
239 | "if" => Some(IF_KW), | ||
240 | "match" => Some(MATCH_KW), | ||
226 | _ => None, | 241 | _ => None, |
227 | } | 242 | } |
228 | } | 243 | } |
diff --git a/tests/data/lexer/0011_keywords.rs b/tests/data/lexer/0011_keywords.rs index c2c9e5667..02ca19089 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 where | fn use struct trait enum impl true false as extern crate mod pub self super in where for loop while if match | ||
diff --git a/tests/data/lexer/0011_keywords.txt b/tests/data/lexer/0011_keywords.txt index 301ee21e2..964e3475a 100644 --- a/tests/data/lexer/0011_keywords.txt +++ b/tests/data/lexer/0011_keywords.txt | |||
@@ -31,4 +31,14 @@ WHITESPACE 1 " " | |||
31 | IN_KW 2 "in" | 31 | IN_KW 2 "in" |
32 | WHITESPACE 1 " " | 32 | WHITESPACE 1 " " |
33 | WHERE_KW 5 "where" | 33 | WHERE_KW 5 "where" |
34 | WHITESPACE 1 " " | ||
35 | FOR_KW 3 "for" | ||
36 | WHITESPACE 1 " " | ||
37 | LOOP_KW 4 "loop" | ||
38 | WHITESPACE 1 " " | ||
39 | WHILE_KW 5 "while" | ||
40 | WHITESPACE 1 " " | ||
41 | IF_KW 2 "if" | ||
42 | WHITESPACE 1 " " | ||
43 | MATCH_KW 5 "match" | ||
34 | WHITESPACE 1 "\n" | 44 | WHITESPACE 1 "\n" |
diff --git a/tests/data/parser/err/0001_item_recovery_in_file.txt b/tests/data/parser/err/0001_item_recovery_in_file.txt index ac0760695..c33113c6d 100644 --- a/tests/data/parser/err/0001_item_recovery_in_file.txt +++ b/tests/data/parser/err/0001_item_recovery_in_file.txt | |||
@@ -1,11 +1,11 @@ | |||
1 | FILE@[0; 21) | 1 | FILE@[0; 21) |
2 | ERROR@[0; 3) | 2 | ERROR@[0; 3) |
3 | err: `expected item` | 3 | err: `expected item` |
4 | IDENT@[0; 2) "if" | 4 | IF_KW@[0; 2) |
5 | WHITESPACE@[2; 3) | 5 | WHITESPACE@[2; 3) |
6 | ERROR@[3; 10) | 6 | ERROR@[3; 10) |
7 | err: `expected item` | 7 | err: `expected item` |
8 | IDENT@[3; 8) "match" | 8 | MATCH_KW@[3; 8) |
9 | WHITESPACE@[8; 10) | 9 | WHITESPACE@[8; 10) |
10 | STRUCT_ITEM@[10; 21) | 10 | STRUCT_ITEM@[10; 21) |
11 | STRUCT_KW@[10; 16) | 11 | STRUCT_KW@[10; 16) |
diff --git a/tests/data/parser/err/0008_item_block_recovery.txt b/tests/data/parser/err/0008_item_block_recovery.txt index df6a952cd..c6386fd73 100644 --- a/tests/data/parser/err/0008_item_block_recovery.txt +++ b/tests/data/parser/err/0008_item_block_recovery.txt | |||
@@ -24,7 +24,7 @@ FILE@[0; 95) | |||
24 | err: `expected item` | 24 | err: `expected item` |
25 | L_CURLY@[20; 21) | 25 | L_CURLY@[20; 21) |
26 | WHITESPACE@[21; 26) | 26 | WHITESPACE@[21; 26) |
27 | IDENT@[26; 28) "if" | 27 | IF_KW@[26; 28) |
28 | WHITESPACE@[28; 29) | 28 | WHITESPACE@[28; 29) |
29 | TRUE_KW@[29; 33) | 29 | TRUE_KW@[29; 33) |
30 | WHITESPACE@[33; 34) | 30 | WHITESPACE@[33; 34) |
diff --git a/tests/data/parser/ok/0020_type_param_bounds.rs b/tests/data/parser/ok/0020_type_param_bounds.rs new file mode 100644 index 000000000..a1b9f00a4 --- /dev/null +++ b/tests/data/parser/ok/0020_type_param_bounds.rs | |||
@@ -0,0 +1,9 @@ | |||
1 | struct A<T>; | ||
2 | struct B<T:>; | ||
3 | struct C<T: 'a>; | ||
4 | struct D<T: 'a + >; | ||
5 | struct E<T: 'a + 'd >; | ||
6 | struct F<T: 'a + 'd + Clone>; | ||
7 | struct G<T: Clone + Copy>; | ||
8 | struct H<T: ::Foo + self::Bar + 'a>; | ||
9 | struct I<T:, U:,>; | ||
diff --git a/tests/data/parser/ok/0020_type_param_bounds.txt b/tests/data/parser/ok/0020_type_param_bounds.txt new file mode 100644 index 000000000..6f65d150a --- /dev/null +++ b/tests/data/parser/ok/0020_type_param_bounds.txt | |||
@@ -0,0 +1,169 @@ | |||
1 | FILE@[0; 200) | ||
2 | STRUCT_ITEM@[0; 13) | ||
3 | STRUCT_KW@[0; 6) | ||
4 | WHITESPACE@[6; 7) | ||
5 | IDENT@[7; 8) "A" | ||
6 | TYPE_PARAM_LIST@[8; 11) | ||
7 | L_ANGLE@[8; 9) | ||
8 | TYPE_PARAM@[9; 10) | ||
9 | IDENT@[9; 10) "T" | ||
10 | R_ANGLE@[10; 11) | ||
11 | SEMI@[11; 12) | ||
12 | WHITESPACE@[12; 13) | ||
13 | STRUCT_ITEM@[13; 27) | ||
14 | STRUCT_KW@[13; 19) | ||
15 | WHITESPACE@[19; 20) | ||
16 | IDENT@[20; 21) "B" | ||
17 | TYPE_PARAM_LIST@[21; 25) | ||
18 | L_ANGLE@[21; 22) | ||
19 | TYPE_PARAM@[22; 24) | ||
20 | IDENT@[22; 23) "T" | ||
21 | COLON@[23; 24) | ||
22 | R_ANGLE@[24; 25) | ||
23 | SEMI@[25; 26) | ||
24 | WHITESPACE@[26; 27) | ||
25 | STRUCT_ITEM@[27; 44) | ||
26 | STRUCT_KW@[27; 33) | ||
27 | WHITESPACE@[33; 34) | ||
28 | IDENT@[34; 35) "C" | ||
29 | TYPE_PARAM_LIST@[35; 42) | ||
30 | L_ANGLE@[35; 36) | ||
31 | TYPE_PARAM@[36; 41) | ||
32 | IDENT@[36; 37) "T" | ||
33 | COLON@[37; 38) | ||
34 | WHITESPACE@[38; 39) | ||
35 | LIFETIME@[39; 41) "'a" | ||
36 | R_ANGLE@[41; 42) | ||
37 | SEMI@[42; 43) | ||
38 | WHITESPACE@[43; 44) | ||
39 | STRUCT_ITEM@[44; 64) | ||
40 | STRUCT_KW@[44; 50) | ||
41 | WHITESPACE@[50; 51) | ||
42 | IDENT@[51; 52) "D" | ||
43 | TYPE_PARAM_LIST@[52; 62) | ||
44 | L_ANGLE@[52; 53) | ||
45 | TYPE_PARAM@[53; 61) | ||
46 | IDENT@[53; 54) "T" | ||
47 | COLON@[54; 55) | ||
48 | WHITESPACE@[55; 56) | ||
49 | LIFETIME@[56; 58) "'a" | ||
50 | WHITESPACE@[58; 59) | ||
51 | PLUS@[59; 60) | ||
52 | WHITESPACE@[60; 61) | ||
53 | R_ANGLE@[61; 62) | ||
54 | SEMI@[62; 63) | ||
55 | WHITESPACE@[63; 64) | ||
56 | STRUCT_ITEM@[64; 87) | ||
57 | STRUCT_KW@[64; 70) | ||
58 | WHITESPACE@[70; 71) | ||
59 | IDENT@[71; 72) "E" | ||
60 | TYPE_PARAM_LIST@[72; 85) | ||
61 | L_ANGLE@[72; 73) | ||
62 | TYPE_PARAM@[73; 84) | ||
63 | IDENT@[73; 74) "T" | ||
64 | COLON@[74; 75) | ||
65 | WHITESPACE@[75; 76) | ||
66 | LIFETIME@[76; 78) "'a" | ||
67 | WHITESPACE@[78; 79) | ||
68 | PLUS@[79; 80) | ||
69 | WHITESPACE@[80; 81) | ||
70 | LIFETIME@[81; 83) "'d" | ||
71 | WHITESPACE@[83; 84) | ||
72 | R_ANGLE@[84; 85) | ||
73 | SEMI@[85; 86) | ||
74 | WHITESPACE@[86; 87) | ||
75 | STRUCT_ITEM@[87; 117) | ||
76 | STRUCT_KW@[87; 93) | ||
77 | WHITESPACE@[93; 94) | ||
78 | IDENT@[94; 95) "F" | ||
79 | TYPE_PARAM_LIST@[95; 115) | ||
80 | L_ANGLE@[95; 96) | ||
81 | TYPE_PARAM@[96; 114) | ||
82 | IDENT@[96; 97) "T" | ||
83 | COLON@[97; 98) | ||
84 | WHITESPACE@[98; 99) | ||
85 | LIFETIME@[99; 101) "'a" | ||
86 | WHITESPACE@[101; 102) | ||
87 | PLUS@[102; 103) | ||
88 | WHITESPACE@[103; 104) | ||
89 | LIFETIME@[104; 106) "'d" | ||
90 | WHITESPACE@[106; 107) | ||
91 | PLUS@[107; 108) | ||
92 | PATH@[108; 114) | ||
93 | PATH_SEGMENT@[108; 114) | ||
94 | WHITESPACE@[108; 109) | ||
95 | IDENT@[109; 114) "Clone" | ||
96 | R_ANGLE@[114; 115) | ||
97 | SEMI@[115; 116) | ||
98 | WHITESPACE@[116; 117) | ||
99 | STRUCT_ITEM@[117; 144) | ||
100 | STRUCT_KW@[117; 123) | ||
101 | WHITESPACE@[123; 124) | ||
102 | IDENT@[124; 125) "G" | ||
103 | TYPE_PARAM_LIST@[125; 142) | ||
104 | L_ANGLE@[125; 126) | ||
105 | TYPE_PARAM@[126; 141) | ||
106 | IDENT@[126; 127) "T" | ||
107 | COLON@[127; 128) | ||
108 | PATH@[128; 135) | ||
109 | PATH_SEGMENT@[128; 135) | ||
110 | WHITESPACE@[128; 129) | ||
111 | IDENT@[129; 134) "Clone" | ||
112 | WHITESPACE@[134; 135) | ||
113 | PLUS@[135; 136) | ||
114 | PATH@[136; 141) | ||
115 | PATH_SEGMENT@[136; 141) | ||
116 | WHITESPACE@[136; 137) | ||
117 | IDENT@[137; 141) "Copy" | ||
118 | R_ANGLE@[141; 142) | ||
119 | SEMI@[142; 143) | ||
120 | WHITESPACE@[143; 144) | ||
121 | STRUCT_ITEM@[144; 181) | ||
122 | STRUCT_KW@[144; 150) | ||
123 | WHITESPACE@[150; 151) | ||
124 | IDENT@[151; 152) "H" | ||
125 | TYPE_PARAM_LIST@[152; 179) | ||
126 | L_ANGLE@[152; 153) | ||
127 | TYPE_PARAM@[153; 178) | ||
128 | IDENT@[153; 154) "T" | ||
129 | COLON@[154; 155) | ||
130 | PATH@[155; 162) | ||
131 | PATH_SEGMENT@[155; 162) | ||
132 | WHITESPACE@[155; 156) | ||
133 | COLONCOLON@[156; 158) | ||
134 | IDENT@[158; 161) "Foo" | ||
135 | WHITESPACE@[161; 162) | ||
136 | PLUS@[162; 163) | ||
137 | PATH@[163; 174) | ||
138 | PATH@[163; 168) | ||
139 | PATH_SEGMENT@[163; 168) | ||
140 | WHITESPACE@[163; 164) | ||
141 | SELF_KW@[164; 168) | ||
142 | COLONCOLON@[168; 170) | ||
143 | PATH_SEGMENT@[170; 174) | ||
144 | IDENT@[170; 173) "Bar" | ||
145 | WHITESPACE@[173; 174) | ||
146 | PLUS@[174; 175) | ||
147 | WHITESPACE@[175; 176) | ||
148 | LIFETIME@[176; 178) "'a" | ||
149 | R_ANGLE@[178; 179) | ||
150 | SEMI@[179; 180) | ||
151 | WHITESPACE@[180; 181) | ||
152 | STRUCT_ITEM@[181; 200) | ||
153 | STRUCT_KW@[181; 187) | ||
154 | WHITESPACE@[187; 188) | ||
155 | IDENT@[188; 189) "I" | ||
156 | TYPE_PARAM_LIST@[189; 198) | ||
157 | L_ANGLE@[189; 190) | ||
158 | TYPE_PARAM@[190; 192) | ||
159 | IDENT@[190; 191) "T" | ||
160 | COLON@[191; 192) | ||
161 | COMMA@[192; 193) | ||
162 | TYPE_PARAM@[193; 196) | ||
163 | WHITESPACE@[193; 194) | ||
164 | IDENT@[194; 195) "U" | ||
165 | COLON@[195; 196) | ||
166 | COMMA@[196; 197) | ||
167 | R_ANGLE@[197; 198) | ||
168 | SEMI@[198; 199) | ||
169 | WHITESPACE@[199; 200) | ||