aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_parser/src/grammar/expressions.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_parser/src/grammar/expressions.rs')
-rw-r--r--crates/ra_parser/src/grammar/expressions.rs49
1 files changed, 9 insertions, 40 deletions
diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs
index ea04b9458..1dd9a586c 100644
--- a/crates/ra_parser/src/grammar/expressions.rs
+++ b/crates/ra_parser/src/grammar/expressions.rs
@@ -14,20 +14,17 @@ const EXPR_FIRST: TokenSet = LHS_FIRST;
14 14
15pub(super) fn expr(p: &mut Parser) -> BlockLike { 15pub(super) fn expr(p: &mut Parser) -> BlockLike {
16 let r = Restrictions { forbid_structs: false, prefer_stmt: false }; 16 let r = Restrictions { forbid_structs: false, prefer_stmt: false };
17 let mut dollar_lvl = 0; 17 expr_bp(p, r, 1).1
18 expr_bp(p, r, 1, &mut dollar_lvl).1
19} 18}
20 19
21pub(super) fn expr_stmt(p: &mut Parser) -> (Option<CompletedMarker>, BlockLike) { 20pub(super) fn expr_stmt(p: &mut Parser) -> (Option<CompletedMarker>, BlockLike) {
22 let r = Restrictions { forbid_structs: false, prefer_stmt: true }; 21 let r = Restrictions { forbid_structs: false, prefer_stmt: true };
23 let mut dollar_lvl = 0; 22 expr_bp(p, r, 1)
24 expr_bp(p, r, 1, &mut dollar_lvl)
25} 23}
26 24
27fn expr_no_struct(p: &mut Parser) { 25fn expr_no_struct(p: &mut Parser) {
28 let r = Restrictions { forbid_structs: true, prefer_stmt: false }; 26 let r = Restrictions { forbid_structs: true, prefer_stmt: false };
29 let mut dollar_lvl = 0; 27 expr_bp(p, r, 1);
30 expr_bp(p, r, 1, &mut dollar_lvl);
31} 28}
32 29
33// test block 30// test block
@@ -257,23 +254,8 @@ fn current_op(p: &Parser) -> (u8, SyntaxKind) {
257} 254}
258 255
259// Parses expression with binding power of at least bp. 256// Parses expression with binding power of at least bp.
260fn expr_bp( 257fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) -> (Option<CompletedMarker>, BlockLike) {
261 p: &mut Parser, 258 let mut lhs = match lhs(p, r) {
262 r: Restrictions,
263 mut bp: u8,
264 dollar_lvl: &mut usize,
265) -> (Option<CompletedMarker>, BlockLike) {
266 // `newly_dollar_open` is a flag indicated that dollar is just closed after lhs, e.g.
267 // `$1$ + a`
268 // We use this flag to skip handling it.
269 let mut newly_dollar_open = if p.at_l_dollar() {
270 *dollar_lvl += p.eat_l_dollars();
271 true
272 } else {
273 false
274 };
275
276 let mut lhs = match lhs(p, r, dollar_lvl) {
277 Some((lhs, blocklike)) => { 259 Some((lhs, blocklike)) => {
278 // test stmt_bin_expr_ambiguity 260 // test stmt_bin_expr_ambiguity
279 // fn foo() { 261 // fn foo() {
@@ -289,15 +271,6 @@ fn expr_bp(
289 }; 271 };
290 272
291 loop { 273 loop {
292 if *dollar_lvl > 0 && p.at_r_dollar() {
293 *dollar_lvl -= p.eat_r_dollars(*dollar_lvl);
294 if !newly_dollar_open {
295 // We "pump" bp for make it highest priority
296 bp = 255;
297 }
298 newly_dollar_open = false;
299 }
300
301 let is_range = p.at(T![..]) || p.at(T![..=]); 274 let is_range = p.at(T![..]) || p.at(T![..=]);
302 let (op_bp, op) = current_op(p); 275 let (op_bp, op) = current_op(p);
303 if op_bp < bp { 276 if op_bp < bp {
@@ -306,7 +279,7 @@ fn expr_bp(
306 let m = lhs.precede(p); 279 let m = lhs.precede(p);
307 p.bump(op); 280 p.bump(op);
308 281
309 expr_bp(p, r, op_bp + 1, dollar_lvl); 282 expr_bp(p, r, op_bp + 1);
310 lhs = m.complete(p, if is_range { RANGE_EXPR } else { BIN_EXPR }); 283 lhs = m.complete(p, if is_range { RANGE_EXPR } else { BIN_EXPR });
311 } 284 }
312 (Some(lhs), BlockLike::NotBlock) 285 (Some(lhs), BlockLike::NotBlock)
@@ -314,11 +287,7 @@ fn expr_bp(
314 287
315const LHS_FIRST: TokenSet = atom::ATOM_EXPR_FIRST.union(token_set![AMP, STAR, EXCL, DOT, MINUS]); 288const LHS_FIRST: TokenSet = atom::ATOM_EXPR_FIRST.union(token_set![AMP, STAR, EXCL, DOT, MINUS]);
316 289
317fn lhs( 290fn lhs(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)> {
318 p: &mut Parser,
319 r: Restrictions,
320 dollar_lvl: &mut usize,
321) -> Option<(CompletedMarker, BlockLike)> {
322 let m; 291 let m;
323 let kind = match p.current() { 292 let kind = match p.current() {
324 // test ref_expr 293 // test ref_expr
@@ -351,7 +320,7 @@ fn lhs(
351 m = p.start(); 320 m = p.start();
352 p.bump(op); 321 p.bump(op);
353 if p.at_ts(EXPR_FIRST) { 322 if p.at_ts(EXPR_FIRST) {
354 expr_bp(p, r, 2, dollar_lvl); 323 expr_bp(p, r, 2);
355 } 324 }
356 return Some((m.complete(p, RANGE_EXPR), BlockLike::NotBlock)); 325 return Some((m.complete(p, RANGE_EXPR), BlockLike::NotBlock));
357 } 326 }
@@ -367,7 +336,7 @@ fn lhs(
367 return Some(postfix_expr(p, lhs, blocklike, !(r.prefer_stmt && blocklike.is_block()))); 336 return Some(postfix_expr(p, lhs, blocklike, !(r.prefer_stmt && blocklike.is_block())));
368 } 337 }
369 }; 338 };
370 expr_bp(p, r, 255, dollar_lvl); 339 expr_bp(p, r, 255);
371 Some((m.complete(p, kind), BlockLike::NotBlock)) 340 Some((m.complete(p, kind), BlockLike::NotBlock))
372} 341}
373 342