aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/grammar.ron10
-rw-r--r--src/parser/grammar/expressions.rs27
-rw-r--r--src/parser/grammar/mod.rs1
-rw-r--r--src/parser/grammar/paths.rs32
-rw-r--r--src/parser/grammar/type_args.rs26
-rw-r--r--src/syntax_kinds/generated.rs16
-rw-r--r--tests/data/parser/inline/0039_path_expr.rs5
-rw-r--r--tests/data/parser/inline/0039_path_expr.txt74
-rw-r--r--tests/data/parser/inline/0040_expr_literals.rs12
-rw-r--r--tests/data/parser/inline/0040_expr_literals.txt134
10 files changed, 320 insertions, 17 deletions
diff --git a/src/grammar.ron b/src/grammar.ron
index d5d2e6162..8232ba1dc 100644
--- a/src/grammar.ron
+++ b/src/grammar.ron
@@ -120,6 +120,7 @@ Grammar(
120 "PLACEHOLDER_PAT", 120 "PLACEHOLDER_PAT",
121 121
122 "TUPLE_EXPR", 122 "TUPLE_EXPR",
123 "PATH_EXPR",
123 124
124 "EXTERN_BLOCK", 125 "EXTERN_BLOCK",
125 "ENUM_VARIANT", 126 "ENUM_VARIANT",
@@ -133,15 +134,18 @@ Grammar(
133 "LITERAL", 134 "LITERAL",
134 "ALIAS", 135 "ALIAS",
135 "VISIBILITY", 136 "VISIBILITY",
136 "TYPE_PARAM_LIST",
137 "WHERE_CLAUSE", 137 "WHERE_CLAUSE",
138 "LIFETIME_PARAM",
139 "TYPE_PARAM",
140 "ABI", 138 "ABI",
141 "NAME", 139 "NAME",
142 "NAME_REF", 140 "NAME_REF",
143 "VALUE_PARAMETER", 141 "VALUE_PARAMETER",
144 "BLOCK", 142 "BLOCK",
145 "LET_STMT", 143 "LET_STMT",
144
145 "TYPE_PARAM",
146 "LIFETIME_PARAM",
147 "TYPE_PARAM_LIST",
148 "TYPE_ARG_LIST",
149
146 ] 150 ]
147) 151)
diff --git a/src/parser/grammar/expressions.rs b/src/parser/grammar/expressions.rs
index 40f41535e..ece698248 100644
--- a/src/parser/grammar/expressions.rs
+++ b/src/parser/grammar/expressions.rs
@@ -2,7 +2,16 @@ use super::*;
2 2
3// test expr_literals 3// test expr_literals
4// fn foo() { 4// fn foo() {
5// let _ = 92; 5// let _ = true;
6// let _ = false;
7// let _ = 1;
8// let _ = 2.0;
9// let _ = b'a';
10// let _ = 'b';
11// let _ = "c";
12// let _ = r"d";
13// let _ = b"e";
14// let _ = br"f";
6// } 15// }
7pub(super) fn literal(p: &mut Parser) -> bool { 16pub(super) fn literal(p: &mut Parser) -> bool {
8 match p.current() { 17 match p.current() {
@@ -21,6 +30,9 @@ pub(super) fn expr(p: &mut Parser) {
21 if literal(p) { 30 if literal(p) {
22 return; 31 return;
23 } 32 }
33 if paths::is_path_start(p) {
34 return path_expr(p);
35 }
24 36
25 match p.current() { 37 match p.current() {
26 L_PAREN => tuple_expr(p), 38 L_PAREN => tuple_expr(p),
@@ -35,3 +47,16 @@ fn tuple_expr(p: &mut Parser) {
35 p.expect(R_PAREN); 47 p.expect(R_PAREN);
36 m.complete(p, TUPLE_EXPR); 48 m.complete(p, TUPLE_EXPR);
37} 49}
50
51// test path_expr
52// fn foo() {
53// let _ = a;
54// let _ = a::b;
55// let _ = ::a::<b>;
56// }
57fn path_expr(p: &mut Parser) {
58 assert!(paths::is_path_start(p));
59 let m = p.start();
60 paths::expr_path(p);
61 m.complete(p, PATH_EXPR);
62}
diff --git a/src/parser/grammar/mod.rs b/src/parser/grammar/mod.rs
index e24f1055e..e4823eadb 100644
--- a/src/parser/grammar/mod.rs
+++ b/src/parser/grammar/mod.rs
@@ -27,6 +27,7 @@ mod items;
27mod paths; 27mod paths;
28mod patterns; 28mod patterns;
29mod type_params; 29mod type_params;
30mod type_args;
30mod types; 31mod types;
31 32
32use { 33use {
diff --git a/src/parser/grammar/paths.rs b/src/parser/grammar/paths.rs
index d3eb20ea1..69ed84665 100644
--- a/src/parser/grammar/paths.rs
+++ b/src/parser/grammar/paths.rs
@@ -8,19 +8,26 @@ pub(super) fn is_path_start(p: &Parser) -> bool {
8} 8}
9 9
10pub(super) fn use_path(p: &mut Parser) { 10pub(super) fn use_path(p: &mut Parser) {
11 path(p) 11 path(p, Mode::Use)
12} 12}
13 13
14pub(super) fn type_path(p: &mut Parser) { 14pub(super) fn type_path(p: &mut Parser) {
15 path(p) 15 path(p, Mode::Type)
16} 16}
17 17
18fn path(p: &mut Parser) { 18pub(super) fn expr_path(p: &mut Parser) {
19 path(p, Mode::Expr)
20}
21
22#[derive(Clone, Copy, Eq, PartialEq)]
23enum Mode { Use, Type, Expr }
24
25fn path(p: &mut Parser, mode: Mode) {
19 if !is_path_start(p) { 26 if !is_path_start(p) {
20 return; 27 return;
21 } 28 }
22 let path = p.start(); 29 let path = p.start();
23 path_segment(p, true); 30 path_segment(p, mode, true);
24 let mut qual = path.complete(p, PATH); 31 let mut qual = path.complete(p, PATH);
25 loop { 32 loop {
26 let use_tree = match p.nth(1) { 33 let use_tree = match p.nth(1) {
@@ -30,7 +37,7 @@ fn path(p: &mut Parser) {
30 if p.at(COLONCOLON) && !use_tree { 37 if p.at(COLONCOLON) && !use_tree {
31 let path = qual.precede(p); 38 let path = qual.precede(p);
32 p.bump(); 39 p.bump();
33 path_segment(p, false); 40 path_segment(p, mode, false);
34 let path = path.complete(p, PATH); 41 let path = path.complete(p, PATH);
35 qual = path; 42 qual = path;
36 } else { 43 } else {
@@ -39,13 +46,16 @@ fn path(p: &mut Parser) {
39 } 46 }
40} 47}
41 48
42fn path_segment(p: &mut Parser, first: bool) { 49fn path_segment(p: &mut Parser, mode: Mode, first: bool) {
43 let segment = p.start(); 50 let segment = p.start();
44 if first { 51 if first {
45 p.eat(COLONCOLON); 52 p.eat(COLONCOLON);
46 } 53 }
47 match p.current() { 54 match p.current() {
48 IDENT => name_ref(p), 55 IDENT => {
56 name_ref(p);
57 path_generic_args(p, mode);
58 },
49 SELF_KW | SUPER_KW => p.bump(), 59 SELF_KW | SUPER_KW => p.bump(),
50 _ => { 60 _ => {
51 p.error("expected identifier"); 61 p.error("expected identifier");
@@ -53,3 +63,11 @@ fn path_segment(p: &mut Parser, first: bool) {
53 }; 63 };
54 segment.complete(p, PATH_SEGMENT); 64 segment.complete(p, PATH_SEGMENT);
55} 65}
66
67fn path_generic_args(p: &mut Parser, mode: Mode) {
68 match mode {
69 Mode::Use => return,
70 Mode::Type => type_args::list(p, false),
71 Mode::Expr => type_args::list(p, true),
72 }
73}
diff --git a/src/parser/grammar/type_args.rs b/src/parser/grammar/type_args.rs
new file mode 100644
index 000000000..20e75b4b0
--- /dev/null
+++ b/src/parser/grammar/type_args.rs
@@ -0,0 +1,26 @@
1use super::*;
2
3pub(super) fn list(p: &mut Parser, colon_colon_required: bool) {
4 let m;
5 match (colon_colon_required, p.nth(0), p.nth(1)) {
6 (_, COLONCOLON, L_ANGLE) => {
7 m = p.start();
8 p.bump();
9 p.bump();
10 }
11 (false, L_ANGLE, _) => {
12 m = p.start();
13 p.bump();
14 }
15 _ => return
16 };
17
18 while !p.at(EOF) && !p.at(R_ANGLE) {
19 types::type_(p);
20 if !p.at(R_ANGLE) && !p.expect(COMMA) {
21 break;
22 }
23 }
24 p.expect(R_ANGLE);
25 m.complete(p, TYPE_ARG_LIST);
26}
diff --git a/src/syntax_kinds/generated.rs b/src/syntax_kinds/generated.rs
index 029972bb3..bc2a995f6 100644
--- a/src/syntax_kinds/generated.rs
+++ b/src/syntax_kinds/generated.rs
@@ -115,6 +115,7 @@ pub enum SyntaxKind {
115 BIND_PAT, 115 BIND_PAT,
116 PLACEHOLDER_PAT, 116 PLACEHOLDER_PAT,
117 TUPLE_EXPR, 117 TUPLE_EXPR,
118 PATH_EXPR,
118 EXTERN_BLOCK, 119 EXTERN_BLOCK,
119 ENUM_VARIANT, 120 ENUM_VARIANT,
120 NAMED_FIELD, 121 NAMED_FIELD,
@@ -127,16 +128,17 @@ pub enum SyntaxKind {
127 LITERAL, 128 LITERAL,
128 ALIAS, 129 ALIAS,
129 VISIBILITY, 130 VISIBILITY,
130 TYPE_PARAM_LIST,
131 WHERE_CLAUSE, 131 WHERE_CLAUSE,
132 LIFETIME_PARAM,
133 TYPE_PARAM,
134 ABI, 132 ABI,
135 NAME, 133 NAME,
136 NAME_REF, 134 NAME_REF,
137 VALUE_PARAMETER, 135 VALUE_PARAMETER,
138 BLOCK, 136 BLOCK,
139 LET_STMT, 137 LET_STMT,
138 TYPE_PARAM,
139 LIFETIME_PARAM,
140 TYPE_PARAM_LIST,
141 TYPE_ARG_LIST,
140 // Technical SyntaxKinds: they appear temporally during parsing, 142 // Technical SyntaxKinds: they appear temporally during parsing,
141 // but never end up in the final tree 143 // but never end up in the final tree
142 #[doc(hidden)] 144 #[doc(hidden)]
@@ -259,6 +261,7 @@ impl SyntaxKind {
259 BIND_PAT => &SyntaxInfo { name: "BIND_PAT" }, 261 BIND_PAT => &SyntaxInfo { name: "BIND_PAT" },
260 PLACEHOLDER_PAT => &SyntaxInfo { name: "PLACEHOLDER_PAT" }, 262 PLACEHOLDER_PAT => &SyntaxInfo { name: "PLACEHOLDER_PAT" },
261 TUPLE_EXPR => &SyntaxInfo { name: "TUPLE_EXPR" }, 263 TUPLE_EXPR => &SyntaxInfo { name: "TUPLE_EXPR" },
264 PATH_EXPR => &SyntaxInfo { name: "PATH_EXPR" },
262 EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" }, 265 EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" },
263 ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" }, 266 ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" },
264 NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" }, 267 NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" },
@@ -271,16 +274,17 @@ impl SyntaxKind {
271 LITERAL => &SyntaxInfo { name: "LITERAL" }, 274 LITERAL => &SyntaxInfo { name: "LITERAL" },
272 ALIAS => &SyntaxInfo { name: "ALIAS" }, 275 ALIAS => &SyntaxInfo { name: "ALIAS" },
273 VISIBILITY => &SyntaxInfo { name: "VISIBILITY" }, 276 VISIBILITY => &SyntaxInfo { name: "VISIBILITY" },
274 TYPE_PARAM_LIST => &SyntaxInfo { name: "TYPE_PARAM_LIST" },
275 WHERE_CLAUSE => &SyntaxInfo { name: "WHERE_CLAUSE" }, 277 WHERE_CLAUSE => &SyntaxInfo { name: "WHERE_CLAUSE" },
276 LIFETIME_PARAM => &SyntaxInfo { name: "LIFETIME_PARAM" },
277 TYPE_PARAM => &SyntaxInfo { name: "TYPE_PARAM" },
278 ABI => &SyntaxInfo { name: "ABI" }, 278 ABI => &SyntaxInfo { name: "ABI" },
279 NAME => &SyntaxInfo { name: "NAME" }, 279 NAME => &SyntaxInfo { name: "NAME" },
280 NAME_REF => &SyntaxInfo { name: "NAME_REF" }, 280 NAME_REF => &SyntaxInfo { name: "NAME_REF" },
281 VALUE_PARAMETER => &SyntaxInfo { name: "VALUE_PARAMETER" }, 281 VALUE_PARAMETER => &SyntaxInfo { name: "VALUE_PARAMETER" },
282 BLOCK => &SyntaxInfo { name: "BLOCK" }, 282 BLOCK => &SyntaxInfo { name: "BLOCK" },
283 LET_STMT => &SyntaxInfo { name: "LET_STMT" }, 283 LET_STMT => &SyntaxInfo { name: "LET_STMT" },
284 TYPE_PARAM => &SyntaxInfo { name: "TYPE_PARAM" },
285 LIFETIME_PARAM => &SyntaxInfo { name: "LIFETIME_PARAM" },
286 TYPE_PARAM_LIST => &SyntaxInfo { name: "TYPE_PARAM_LIST" },
287 TYPE_ARG_LIST => &SyntaxInfo { name: "TYPE_ARG_LIST" },
284 288
285 TOMBSTONE => &SyntaxInfo { name: "TOMBSTONE" }, 289 TOMBSTONE => &SyntaxInfo { name: "TOMBSTONE" },
286 EOF => &SyntaxInfo { name: "EOF" }, 290 EOF => &SyntaxInfo { name: "EOF" },
diff --git a/tests/data/parser/inline/0039_path_expr.rs b/tests/data/parser/inline/0039_path_expr.rs
new file mode 100644
index 000000000..e9855bad7
--- /dev/null
+++ b/tests/data/parser/inline/0039_path_expr.rs
@@ -0,0 +1,5 @@
1fn foo() {
2 let _ = a;
3 let _ = a::b;
4 let _ = ::a::<b>;
5}
diff --git a/tests/data/parser/inline/0039_path_expr.txt b/tests/data/parser/inline/0039_path_expr.txt
new file mode 100644
index 000000000..d149fbb75
--- /dev/null
+++ b/tests/data/parser/inline/0039_path_expr.txt
@@ -0,0 +1,74 @@
1FILE@[0; 68)
2 FN_ITEM@[0; 68)
3 FN_KW@[0; 2)
4 NAME@[2; 6)
5 WHITESPACE@[2; 3)
6 IDENT@[3; 6) "foo"
7 L_PAREN@[6; 7)
8 R_PAREN@[7; 8)
9 BLOCK@[8; 68)
10 WHITESPACE@[8; 9)
11 L_CURLY@[9; 10)
12 LET_STMT@[10; 30)
13 WHITESPACE@[10; 15)
14 LET_KW@[15; 18)
15 PLACEHOLDER_PAT@[18; 21)
16 WHITESPACE@[18; 19)
17 UNDERSCORE@[19; 20)
18 WHITESPACE@[20; 21)
19 EQ@[21; 22)
20 PATH_EXPR@[22; 24)
21 PATH@[22; 24)
22 PATH_SEGMENT@[22; 24)
23 NAME_REF@[22; 24)
24 WHITESPACE@[22; 23)
25 IDENT@[23; 24) "a"
26 SEMI@[24; 25)
27 WHITESPACE@[25; 30)
28 LET_STMT@[30; 48)
29 LET_KW@[30; 33)
30 PLACEHOLDER_PAT@[33; 36)
31 WHITESPACE@[33; 34)
32 UNDERSCORE@[34; 35)
33 WHITESPACE@[35; 36)
34 EQ@[36; 37)
35 PATH_EXPR@[37; 42)
36 PATH@[37; 42)
37 PATH@[37; 39)
38 PATH_SEGMENT@[37; 39)
39 NAME_REF@[37; 39)
40 WHITESPACE@[37; 38)
41 IDENT@[38; 39) "a"
42 COLONCOLON@[39; 41)
43 PATH_SEGMENT@[41; 42)
44 NAME_REF@[41; 42)
45 IDENT@[41; 42) "b"
46 SEMI@[42; 43)
47 WHITESPACE@[43; 48)
48 LET_STMT@[48; 66)
49 LET_KW@[48; 51)
50 PLACEHOLDER_PAT@[51; 54)
51 WHITESPACE@[51; 52)
52 UNDERSCORE@[52; 53)
53 WHITESPACE@[53; 54)
54 EQ@[54; 55)
55 PATH_EXPR@[55; 64)
56 PATH@[55; 64)
57 PATH_SEGMENT@[55; 64)
58 WHITESPACE@[55; 56)
59 COLONCOLON@[56; 58)
60 NAME_REF@[58; 59)
61 IDENT@[58; 59) "a"
62 TYPE_ARG_LIST@[59; 64)
63 COLONCOLON@[59; 61)
64 L_ANGLE@[61; 62)
65 PATH_TYPE@[62; 63)
66 PATH@[62; 63)
67 PATH_SEGMENT@[62; 63)
68 NAME_REF@[62; 63)
69 IDENT@[62; 63) "b"
70 R_ANGLE@[63; 64)
71 SEMI@[64; 65)
72 WHITESPACE@[65; 66)
73 R_CURLY@[66; 67)
74 WHITESPACE@[67; 68)
diff --git a/tests/data/parser/inline/0040_expr_literals.rs b/tests/data/parser/inline/0040_expr_literals.rs
new file mode 100644
index 000000000..2e11a5a6e
--- /dev/null
+++ b/tests/data/parser/inline/0040_expr_literals.rs
@@ -0,0 +1,12 @@
1fn foo() {
2 let _ = true;
3 let _ = false;
4 let _ = 1;
5 let _ = 2.0;
6 let _ = b'a';
7 let _ = 'b';
8 let _ = "c";
9 let _ = r"d";
10 let _ = b"e";
11 let _ = br"f";
12}
diff --git a/tests/data/parser/inline/0040_expr_literals.txt b/tests/data/parser/inline/0040_expr_literals.txt
new file mode 100644
index 000000000..83d72bf95
--- /dev/null
+++ b/tests/data/parser/inline/0040_expr_literals.txt
@@ -0,0 +1,134 @@
1FILE@[0; 189)
2 FN_ITEM@[0; 189)
3 FN_KW@[0; 2)
4 NAME@[2; 6)
5 WHITESPACE@[2; 3)
6 IDENT@[3; 6) "foo"
7 L_PAREN@[6; 7)
8 R_PAREN@[7; 8)
9 BLOCK@[8; 189)
10 WHITESPACE@[8; 9)
11 L_CURLY@[9; 10)
12 LET_STMT@[10; 33)
13 WHITESPACE@[10; 15)
14 LET_KW@[15; 18)
15 PLACEHOLDER_PAT@[18; 21)
16 WHITESPACE@[18; 19)
17 UNDERSCORE@[19; 20)
18 WHITESPACE@[20; 21)
19 EQ@[21; 22)
20 LITERAL@[22; 27)
21 WHITESPACE@[22; 23)
22 TRUE_KW@[23; 27)
23 SEMI@[27; 28)
24 WHITESPACE@[28; 33)
25 LET_STMT@[33; 52)
26 LET_KW@[33; 36)
27 PLACEHOLDER_PAT@[36; 39)
28 WHITESPACE@[36; 37)
29 UNDERSCORE@[37; 38)
30 WHITESPACE@[38; 39)
31 EQ@[39; 40)
32 LITERAL@[40; 46)
33 WHITESPACE@[40; 41)
34 FALSE_KW@[41; 46)
35 SEMI@[46; 47)
36 WHITESPACE@[47; 52)
37 LET_STMT@[52; 67)
38 LET_KW@[52; 55)
39 PLACEHOLDER_PAT@[55; 58)
40 WHITESPACE@[55; 56)
41 UNDERSCORE@[56; 57)
42 WHITESPACE@[57; 58)
43 EQ@[58; 59)
44 LITERAL@[59; 61)
45 WHITESPACE@[59; 60)
46 INT_NUMBER@[60; 61)
47 SEMI@[61; 62)
48 WHITESPACE@[62; 67)
49 LET_STMT@[67; 84)
50 LET_KW@[67; 70)
51 PLACEHOLDER_PAT@[70; 73)
52 WHITESPACE@[70; 71)
53 UNDERSCORE@[71; 72)
54 WHITESPACE@[72; 73)
55 EQ@[73; 74)
56 LITERAL@[74; 78)
57 WHITESPACE@[74; 75)
58 FLOAT_NUMBER@[75; 78)
59 SEMI@[78; 79)
60 WHITESPACE@[79; 84)
61 LET_STMT@[84; 102)
62 LET_KW@[84; 87)
63 PLACEHOLDER_PAT@[87; 90)
64 WHITESPACE@[87; 88)
65 UNDERSCORE@[88; 89)
66 WHITESPACE@[89; 90)
67 EQ@[90; 91)
68 LITERAL@[91; 96)
69 WHITESPACE@[91; 92)
70 BYTE@[92; 96)
71 SEMI@[96; 97)
72 WHITESPACE@[97; 102)
73 LET_STMT@[102; 119)
74 LET_KW@[102; 105)
75 PLACEHOLDER_PAT@[105; 108)
76 WHITESPACE@[105; 106)
77 UNDERSCORE@[106; 107)
78 WHITESPACE@[107; 108)
79 EQ@[108; 109)
80 LITERAL@[109; 113)
81 WHITESPACE@[109; 110)
82 CHAR@[110; 113)
83 SEMI@[113; 114)
84 WHITESPACE@[114; 119)
85 LET_STMT@[119; 136)
86 LET_KW@[119; 122)
87 PLACEHOLDER_PAT@[122; 125)
88 WHITESPACE@[122; 123)
89 UNDERSCORE@[123; 124)
90 WHITESPACE@[124; 125)
91 EQ@[125; 126)
92 LITERAL@[126; 130)
93 WHITESPACE@[126; 127)
94 STRING@[127; 130)
95 SEMI@[130; 131)
96 WHITESPACE@[131; 136)
97 LET_STMT@[136; 154)
98 LET_KW@[136; 139)
99 PLACEHOLDER_PAT@[139; 142)
100 WHITESPACE@[139; 140)
101 UNDERSCORE@[140; 141)
102 WHITESPACE@[141; 142)
103 EQ@[142; 143)
104 LITERAL@[143; 148)
105 WHITESPACE@[143; 144)
106 RAW_STRING@[144; 148)
107 SEMI@[148; 149)
108 WHITESPACE@[149; 154)
109 LET_STMT@[154; 172)
110 LET_KW@[154; 157)
111 PLACEHOLDER_PAT@[157; 160)
112 WHITESPACE@[157; 158)
113 UNDERSCORE@[158; 159)
114 WHITESPACE@[159; 160)
115 EQ@[160; 161)
116 LITERAL@[161; 166)
117 WHITESPACE@[161; 162)
118 BYTE_STRING@[162; 166)
119 SEMI@[166; 167)
120 WHITESPACE@[167; 172)
121 LET_STMT@[172; 187)
122 LET_KW@[172; 175)
123 PLACEHOLDER_PAT@[175; 178)
124 WHITESPACE@[175; 176)
125 UNDERSCORE@[176; 177)
126 WHITESPACE@[177; 178)
127 EQ@[178; 179)
128 LITERAL@[179; 185)
129 WHITESPACE@[179; 180)
130 RAW_BYTE_STRING@[180; 185)
131 SEMI@[185; 186)
132 WHITESPACE@[186; 187)
133 R_CURLY@[187; 188)
134 WHITESPACE@[188; 189)