aboutsummaryrefslogtreecommitdiff
path: root/src/grammar
diff options
context:
space:
mode:
Diffstat (limited to 'src/grammar')
-rw-r--r--src/grammar/expressions/atom.rs12
-rw-r--r--src/grammar/expressions/mod.rs110
2 files changed, 63 insertions, 59 deletions
diff --git a/src/grammar/expressions/atom.rs b/src/grammar/expressions/atom.rs
index 95c811730..ad654df9e 100644
--- a/src/grammar/expressions/atom.rs
+++ b/src/grammar/expressions/atom.rs
@@ -33,13 +33,13 @@ pub(super) const ATOM_EXPR_FIRST: TokenSet =
33 IDENT, SELF_KW, SUPER_KW, COLONCOLON ], 33 IDENT, SELF_KW, SUPER_KW, COLONCOLON ],
34 ]; 34 ];
35 35
36pub(super) fn atom_expr(p: &mut Parser) -> Option<CompletedMarker> { 36pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<CompletedMarker> {
37 match literal(p) { 37 match literal(p) {
38 Some(m) => return Some(m), 38 Some(m) => return Some(m),
39 None => (), 39 None => (),
40 } 40 }
41 if paths::is_path_start(p) { 41 if paths::is_path_start(p) {
42 return Some(path_expr(p)); 42 return Some(path_expr(p, r));
43 } 43 }
44 let la = p.nth(1); 44 let la = p.nth(1);
45 let done = match p.current() { 45 let done = match p.current() {
@@ -91,7 +91,8 @@ fn lambda_expr(p: &mut Parser) -> CompletedMarker {
91// fn foo() { 91// fn foo() {
92// if true {}; 92// if true {};
93// if true {} else {}; 93// if true {} else {};
94// if true {} else if false {} else {} 94// if true {} else if false {} else {};
95// if S {};
95// } 96// }
96fn if_expr(p: &mut Parser) -> CompletedMarker { 97fn if_expr(p: &mut Parser) -> CompletedMarker {
97 assert!(p.at(IF_KW)); 98 assert!(p.at(IF_KW));
@@ -112,18 +113,19 @@ fn if_expr(p: &mut Parser) -> CompletedMarker {
112fn if_head(p: &mut Parser) { 113fn if_head(p: &mut Parser) {
113 assert!(p.at(IF_KW)); 114 assert!(p.at(IF_KW));
114 p.bump(); 115 p.bump();
115 expr(p); 116 expr_no_struct(p);
116} 117}
117 118
118// test match_expr 119// test match_expr
119// fn foo() { 120// fn foo() {
120// match () { }; 121// match () { };
122// match S {};
121// } 123// }
122fn match_expr(p: &mut Parser) -> CompletedMarker { 124fn match_expr(p: &mut Parser) -> CompletedMarker {
123 assert!(p.at(MATCH_KW)); 125 assert!(p.at(MATCH_KW));
124 let m = p.start(); 126 let m = p.start();
125 p.bump(); 127 p.bump();
126 expr(p); 128 expr_no_struct(p);
127 p.eat(L_CURLY); 129 p.eat(L_CURLY);
128 while !p.at(EOF) && !p.at(R_CURLY) { 130 while !p.at(EOF) && !p.at(R_CURLY) {
129 match_arm(p); 131 match_arm(p);
diff --git a/src/grammar/expressions/mod.rs b/src/grammar/expressions/mod.rs
index f2b0c36f5..cedbc235f 100644
--- a/src/grammar/expressions/mod.rs
+++ b/src/grammar/expressions/mod.rs
@@ -6,7 +6,13 @@ pub(super) use self::atom::literal;
6const EXPR_FIRST: TokenSet = UNARY_EXPR_FIRST; 6const EXPR_FIRST: TokenSet = UNARY_EXPR_FIRST;
7 7
8pub(super) fn expr(p: &mut Parser) { 8pub(super) fn expr(p: &mut Parser) {
9 expr_bp(p, 1) 9 let r = Restrictions { forbid_structs: false };
10 expr_bp(p, r, 1)
11}
12
13fn expr_no_struct(p: &mut Parser) {
14 let r = Restrictions { forbid_structs: true };
15 expr_bp(p, r, 1)
10} 16}
11 17
12// test block 18// test block
@@ -22,6 +28,11 @@ pub(super) fn block(p: &mut Parser) {
22 atom::block_expr(p); 28 atom::block_expr(p);
23} 29}
24 30
31#[derive(Clone, Copy)]
32struct Restrictions {
33 forbid_structs: bool
34}
35
25// test expr_binding_power 36// test expr_binding_power
26// fn foo() { 37// fn foo() {
27// 1 + 2 * 3 == 1 * 2 + 3 38// 1 + 2 * 3 == 1 * 2 + 3
@@ -36,8 +47,8 @@ fn bp_of(op: SyntaxKind) -> u8 {
36} 47}
37 48
38// Parses expression with binding power of at least bp. 49// Parses expression with binding power of at least bp.
39fn expr_bp(p: &mut Parser, bp: u8) { 50fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) {
40 let mut lhs = match unary_expr(p) { 51 let mut lhs = match unary_expr(p, r) {
41 Some(lhs) => lhs, 52 Some(lhs) => lhs,
42 None => return, 53 None => return,
43 }; 54 };
@@ -47,7 +58,7 @@ fn expr_bp(p: &mut Parser, bp: u8) {
47 if op_bp < bp { 58 if op_bp < bp {
48 break; 59 break;
49 } 60 }
50 lhs = bin_expr(p, lhs, op_bp); 61 lhs = bin_expr(p, r, lhs, op_bp);
51 } 62 }
52} 63}
53 64
@@ -57,17 +68,46 @@ const UNARY_EXPR_FIRST: TokenSet =
57 atom::ATOM_EXPR_FIRST, 68 atom::ATOM_EXPR_FIRST,
58 ]; 69 ];
59 70
60fn unary_expr(p: &mut Parser) -> Option<CompletedMarker> { 71fn unary_expr(p: &mut Parser, r: Restrictions) -> Option<CompletedMarker> {
61 let done = match p.current() { 72 let m;
62 AMPERSAND => ref_expr(p), 73 let kind = match p.current() {
63 STAR => deref_expr(p), 74 // test ref_expr
64 EXCL => not_expr(p), 75 // fn foo() {
76 // let _ = &1;
77 // let _ = &mut &f();
78 // }
79 AMPERSAND => {
80 m = p.start();
81 p.bump();
82 p.eat(MUT_KW);
83 REF_EXPR
84
85 },
86 // test deref_expr
87 // fn foo() {
88 // **&1;
89 // }
90 STAR => {
91 m = p.start();
92 p.bump();
93 DEREF_EXPR
94 },
95 // test not_expr
96 // fn foo() {
97 // !!true;
98 // }
99 EXCL => {
100 m = p.start();
101 p.bump();
102 NOT_EXPR
103 },
65 _ => { 104 _ => {
66 let lhs = atom::atom_expr(p)?; 105 let lhs = atom::atom_expr(p, r)?;
67 postfix_expr(p, lhs) 106 return Some(postfix_expr(p, lhs))
68 } 107 }
69 }; 108 };
70 Some(done) 109 expr(p);
110 Some(m.complete(p, kind))
71} 111}
72 112
73fn postfix_expr(p: &mut Parser, mut lhs: CompletedMarker) -> CompletedMarker { 113fn postfix_expr(p: &mut Parser, mut lhs: CompletedMarker) -> CompletedMarker {
@@ -87,44 +127,6 @@ fn postfix_expr(p: &mut Parser, mut lhs: CompletedMarker) -> CompletedMarker {
87 lhs 127 lhs
88} 128}
89 129
90// test ref_expr
91// fn foo() {
92// let _ = &1;
93// let _ = &mut &f();
94// }
95fn ref_expr(p: &mut Parser) -> CompletedMarker {
96 assert!(p.at(AMPERSAND));
97 let m = p.start();
98 p.bump();
99 p.eat(MUT_KW);
100 expr(p);
101 m.complete(p, REF_EXPR)
102}
103
104// test deref_expr
105// fn foo() {
106// **&1;
107// }
108fn deref_expr(p: &mut Parser) -> CompletedMarker {
109 assert!(p.at(STAR));
110 let m = p.start();
111 p.bump();
112 expr(p);
113 m.complete(p, DEREF_EXPR)
114}
115
116// test not_expr
117// fn foo() {
118// !!true;
119// }
120fn not_expr(p: &mut Parser) -> CompletedMarker {
121 assert!(p.at(EXCL));
122 let m = p.start();
123 p.bump();
124 expr(p);
125 m.complete(p, NOT_EXPR)
126}
127
128// test call_expr 130// test call_expr
129// fn foo() { 131// fn foo() {
130// let _ = f(); 132// let _ = f();
@@ -199,11 +201,11 @@ fn arg_list(p: &mut Parser) {
199// let _ = a::b; 201// let _ = a::b;
200// let _ = ::a::<b>; 202// let _ = ::a::<b>;
201// } 203// }
202fn path_expr(p: &mut Parser) -> CompletedMarker { 204fn path_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker {
203 assert!(paths::is_path_start(p)); 205 assert!(paths::is_path_start(p));
204 let m = p.start(); 206 let m = p.start();
205 paths::expr_path(p); 207 paths::expr_path(p);
206 if p.at(L_CURLY) { 208 if p.at(L_CURLY) && !r.forbid_structs {
207 struct_lit(p); 209 struct_lit(p);
208 m.complete(p, STRUCT_LIT) 210 m.complete(p, STRUCT_LIT)
209 } else { 211 } else {
@@ -243,13 +245,13 @@ fn struct_lit(p: &mut Parser) {
243 p.expect(R_CURLY); 245 p.expect(R_CURLY);
244} 246}
245 247
246fn bin_expr(p: &mut Parser, lhs: CompletedMarker, bp: u8) -> CompletedMarker { 248fn bin_expr(p: &mut Parser, r: Restrictions, lhs: CompletedMarker, bp: u8) -> CompletedMarker {
247 assert!(match p.current() { 249 assert!(match p.current() {
248 MINUS | PLUS | STAR | SLASH | EQEQ | NEQ => true, 250 MINUS | PLUS | STAR | SLASH | EQEQ | NEQ => true,
249 _ => false, 251 _ => false,
250 }); 252 });
251 let m = lhs.precede(p); 253 let m = lhs.precede(p);
252 p.bump(); 254 p.bump();
253 expr_bp(p, bp); 255 expr_bp(p, r, bp);
254 m.complete(p, BIN_EXPR) 256 m.complete(p, BIN_EXPR)
255} 257}