From 20bbe0127cc6bfac3ced0c7ed1de4f0526f3bbed Mon Sep 17 00:00:00 2001 From: DJMcNab <36049421+DJMcNab@users.noreply.github.com> Date: Mon, 17 Dec 2018 22:34:18 +0000 Subject: [PATCH] Fix parsing of inclusive ranges (#214) I'm not certain that this is correct, so extra eyes would be good --- crates/ra_syntax/src/grammar/expressions.rs | 4 +- crates/ra_syntax/src/grammar/patterns.rs | 8 +- .../data/parser/inline/0094_range_pat.rs | 6 +- .../data/parser/inline/0094_range_pat.txt | 86 +++++++++++++------ .../tests/data/parser/ok/0029_range_forms.rs | 5 ++ .../tests/data/parser/ok/0029_range_forms.txt | 86 +++++++++++++++++-- 6 files changed, 158 insertions(+), 37 deletions(-) diff --git a/crates/ra_syntax/src/grammar/expressions.rs b/crates/ra_syntax/src/grammar/expressions.rs index a9449c7bf83..bca32f707f5 100644 --- a/crates/ra_syntax/src/grammar/expressions.rs +++ b/crates/ra_syntax/src/grammar/expressions.rs @@ -143,7 +143,7 @@ fn current_op(p: &Parser) -> (u8, Op) { let bp = match p.current() { EQ => 1, - DOTDOT => 2, + DOTDOT | DOTDOTEQ => 2, EQEQ | NEQ | L_ANGLE | R_ANGLE => 5, PIPE => 6, CARET => 7, @@ -173,7 +173,7 @@ fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) -> BlockLike { }; loop { - let is_range = p.current() == DOTDOT; + let is_range = p.current() == DOTDOT || p.current() == DOTDOTEQ; let (op_bp, op) = current_op(p); if op_bp < bp { break; diff --git a/crates/ra_syntax/src/grammar/patterns.rs b/crates/ra_syntax/src/grammar/patterns.rs index 10fa0e0be14..64cdf0b1b04 100644 --- a/crates/ra_syntax/src/grammar/patterns.rs +++ b/crates/ra_syntax/src/grammar/patterns.rs @@ -14,9 +14,13 @@ pub(super) fn pattern_r(p: &mut Parser, recovery_set: TokenSet) { if let Some(lhs) = atom_pat(p, recovery_set) { // test range_pat // fn main() { - // match 92 { 0 ... 100 => () } + // match 92 { + // 0 ... 100 => (), + // 101 ..= 200 => (), + // 200 .. 301=> (), + // } // } - if p.at(DOTDOTDOT) { + if p.at(DOTDOTDOT) || p.at(DOTDOTEQ) || p.at(DOTDOT) { let m = lhs.precede(p); p.bump(); atom_pat(p, recovery_set); diff --git a/crates/ra_syntax/tests/data/parser/inline/0094_range_pat.rs b/crates/ra_syntax/tests/data/parser/inline/0094_range_pat.rs index 657467e755a..3bca7bf5d4d 100644 --- a/crates/ra_syntax/tests/data/parser/inline/0094_range_pat.rs +++ b/crates/ra_syntax/tests/data/parser/inline/0094_range_pat.rs @@ -1,3 +1,7 @@ fn main() { - match 92 { 0 ... 100 => () } + match 92 { + 0 ... 100 => (), + 101 ..= 200 => (), + 200 .. 301=> (), + } } diff --git a/crates/ra_syntax/tests/data/parser/inline/0094_range_pat.txt b/crates/ra_syntax/tests/data/parser/inline/0094_range_pat.txt index 12ccc1314b1..7eb0fcdf48b 100644 --- a/crates/ra_syntax/tests/data/parser/inline/0094_range_pat.txt +++ b/crates/ra_syntax/tests/data/parser/inline/0094_range_pat.txt @@ -1,5 +1,5 @@ -SOURCE_FILE@[0; 47) - FN_DEF@[0; 46) +SOURCE_FILE@[0; 113) + FN_DEF@[0; 112) FN_KW@[0; 2) WHITESPACE@[2; 3) NAME@[3; 7) @@ -8,35 +8,69 @@ SOURCE_FILE@[0; 47) L_PAREN@[7; 8) R_PAREN@[8; 9) WHITESPACE@[9; 10) - BLOCK@[10; 46) + BLOCK@[10; 112) L_CURLY@[10; 11) WHITESPACE@[11; 16) - MATCH_EXPR@[16; 44) + MATCH_EXPR@[16; 110) MATCH_KW@[16; 21) WHITESPACE@[21; 22) LITERAL@[22; 24) INT_NUMBER@[22; 24) "92" WHITESPACE@[24; 25) - MATCH_ARM_LIST@[25; 44) + MATCH_ARM_LIST@[25; 110) L_CURLY@[25; 26) - WHITESPACE@[26; 27) - MATCH_ARM@[27; 42) - RANGE_PAT@[27; 36) - LITERAL@[27; 28) - INT_NUMBER@[27; 28) "0" - WHITESPACE@[28; 29) - DOTDOTDOT@[29; 32) - WHITESPACE@[32; 33) - LITERAL@[33; 36) - INT_NUMBER@[33; 36) "100" - WHITESPACE@[36; 37) - FAT_ARROW@[37; 39) - WHITESPACE@[39; 40) - TUPLE_EXPR@[40; 42) - L_PAREN@[40; 41) - R_PAREN@[41; 42) - WHITESPACE@[42; 43) - R_CURLY@[43; 44) - WHITESPACE@[44; 45) - R_CURLY@[45; 46) - WHITESPACE@[46; 47) + WHITESPACE@[26; 36) + MATCH_ARM@[36; 51) + RANGE_PAT@[36; 45) + LITERAL@[36; 37) + INT_NUMBER@[36; 37) "0" + WHITESPACE@[37; 38) + DOTDOTDOT@[38; 41) + WHITESPACE@[41; 42) + LITERAL@[42; 45) + INT_NUMBER@[42; 45) "100" + WHITESPACE@[45; 46) + FAT_ARROW@[46; 48) + WHITESPACE@[48; 49) + TUPLE_EXPR@[49; 51) + L_PAREN@[49; 50) + R_PAREN@[50; 51) + COMMA@[51; 52) + WHITESPACE@[52; 61) + MATCH_ARM@[61; 78) + RANGE_PAT@[61; 72) + LITERAL@[61; 64) + INT_NUMBER@[61; 64) "101" + WHITESPACE@[64; 65) + DOTDOTEQ@[65; 68) + WHITESPACE@[68; 69) + LITERAL@[69; 72) + INT_NUMBER@[69; 72) "200" + WHITESPACE@[72; 73) + FAT_ARROW@[73; 75) + WHITESPACE@[75; 76) + TUPLE_EXPR@[76; 78) + L_PAREN@[76; 77) + R_PAREN@[77; 78) + COMMA@[78; 79) + WHITESPACE@[79; 88) + MATCH_ARM@[88; 103) + RANGE_PAT@[88; 98) + LITERAL@[88; 91) + INT_NUMBER@[88; 91) "200" + WHITESPACE@[91; 92) + DOTDOT@[92; 94) + WHITESPACE@[94; 95) + LITERAL@[95; 98) + INT_NUMBER@[95; 98) "301" + FAT_ARROW@[98; 100) + WHITESPACE@[100; 101) + TUPLE_EXPR@[101; 103) + L_PAREN@[101; 102) + R_PAREN@[102; 103) + COMMA@[103; 104) + WHITESPACE@[104; 109) + R_CURLY@[109; 110) + WHITESPACE@[110; 111) + R_CURLY@[111; 112) + WHITESPACE@[112; 113) diff --git a/crates/ra_syntax/tests/data/parser/ok/0029_range_forms.rs b/crates/ra_syntax/tests/data/parser/ok/0029_range_forms.rs index 03f4ae7b208..f9ff444d400 100644 --- a/crates/ra_syntax/tests/data/parser/ok/0029_range_forms.rs +++ b/crates/ra_syntax/tests/data/parser/ok/0029_range_forms.rs @@ -3,4 +3,9 @@ fn foo() { ..z = 2; x = false..1 == 1; let x = 1..; + + ..=1 + 1; + ..=z = 2; + x = false..=1 == 1; + let x = 1..; } diff --git a/crates/ra_syntax/tests/data/parser/ok/0029_range_forms.txt b/crates/ra_syntax/tests/data/parser/ok/0029_range_forms.txt index 2e7703c213e..e3706bfbd0f 100644 --- a/crates/ra_syntax/tests/data/parser/ok/0029_range_forms.txt +++ b/crates/ra_syntax/tests/data/parser/ok/0029_range_forms.txt @@ -1,5 +1,5 @@ -SOURCE_FILE@[0; 79) - FN_DEF@[0; 78) +SOURCE_FILE@[0; 153) + FN_DEF@[0; 152) FN_KW@[0; 2) WHITESPACE@[2; 3) NAME@[3; 6) @@ -8,7 +8,7 @@ SOURCE_FILE@[0; 79) L_PAREN@[6; 7) R_PAREN@[7; 8) WHITESPACE@[8; 9) - BLOCK@[9; 78) + BLOCK@[9; 152) L_CURLY@[9; 10) WHITESPACE@[10; 15) EXPR_STMT@[15; 23) @@ -78,6 +78,80 @@ SOURCE_FILE@[0; 79) INT_NUMBER@[72; 73) "1" DOTDOT@[73; 75) SEMI@[75; 76) - WHITESPACE@[76; 77) - R_CURLY@[77; 78) - WHITESPACE@[78; 79) + WHITESPACE@[76; 86) + err: `expected expression` + EXPR_STMT@[86; 89) + ERROR@[86; 89) + DOTDOTEQ@[86; 89) + err: `expected SEMI` + EXPR_STMT@[89; 95) + BIN_EXPR@[89; 94) + LITERAL@[89; 90) + INT_NUMBER@[89; 90) "1" + WHITESPACE@[90; 91) + PLUS@[91; 92) + WHITESPACE@[92; 93) + LITERAL@[93; 94) + INT_NUMBER@[93; 94) "1" + SEMI@[94; 95) + WHITESPACE@[95; 100) + err: `expected expression` + EXPR_STMT@[100; 103) + ERROR@[100; 103) + DOTDOTEQ@[100; 103) + err: `expected SEMI` + EXPR_STMT@[103; 109) + BIN_EXPR@[103; 108) + PATH_EXPR@[103; 104) + PATH@[103; 104) + PATH_SEGMENT@[103; 104) + NAME_REF@[103; 104) + IDENT@[103; 104) "z" + WHITESPACE@[104; 105) + EQ@[105; 106) + WHITESPACE@[106; 107) + LITERAL@[107; 108) + INT_NUMBER@[107; 108) "2" + SEMI@[108; 109) + WHITESPACE@[109; 114) + EXPR_STMT@[114; 133) + BIN_EXPR@[114; 132) + PATH_EXPR@[114; 115) + PATH@[114; 115) + PATH_SEGMENT@[114; 115) + NAME_REF@[114; 115) + IDENT@[114; 115) "x" + WHITESPACE@[115; 116) + EQ@[116; 117) + WHITESPACE@[117; 118) + RANGE_EXPR@[118; 132) + LITERAL@[118; 123) + FALSE_KW@[118; 123) + DOTDOTEQ@[123; 126) + BIN_EXPR@[126; 132) + LITERAL@[126; 127) + INT_NUMBER@[126; 127) "1" + WHITESPACE@[127; 128) + EQEQ@[128; 130) + WHITESPACE@[130; 131) + LITERAL@[131; 132) + INT_NUMBER@[131; 132) "1" + SEMI@[132; 133) + WHITESPACE@[133; 138) + LET_STMT@[138; 150) + LET_KW@[138; 141) + WHITESPACE@[141; 142) + BIND_PAT@[142; 143) + NAME@[142; 143) + IDENT@[142; 143) "x" + WHITESPACE@[143; 144) + EQ@[144; 145) + WHITESPACE@[145; 146) + RANGE_EXPR@[146; 149) + LITERAL@[146; 147) + INT_NUMBER@[146; 147) "1" + DOTDOT@[147; 149) + SEMI@[149; 150) + WHITESPACE@[150; 151) + R_CURLY@[151; 152) + WHITESPACE@[152; 153)