From 197a2e6fefd45627920cfb9bbca24b446e5a7c89 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 30 Jan 2018 22:53:19 +0300 Subject: [PATCH 1/2] G: type_parameter_list --- grammar.ron | 5 + src/parser/event_parser/grammar/items/mod.rs | 26 ++- src/parser/event_parser/grammar/paths.rs | 13 +- src/syntax_kinds.rs | 15 ++ tests/data/lexer/0011_keywords.rs | 2 +- tests/data/lexer/0011_keywords.txt | 10 ++ .../parser/err/0001_item_recovery_in_file.txt | 4 +- .../parser/err/0008_item_block_recovery.txt | 2 +- .../data/parser/ok/0020_type_param_bounds.rs | 9 + .../data/parser/ok/0020_type_param_bounds.txt | 169 ++++++++++++++++++ 10 files changed, 248 insertions(+), 7 deletions(-) create mode 100644 tests/data/parser/ok/0020_type_param_bounds.rs create mode 100644 tests/data/parser/ok/0020_type_param_bounds.txt diff --git a/grammar.ron b/grammar.ron index d7fea44fbe..8585fd2d4d 100644 --- a/grammar.ron +++ b/grammar.ron @@ -17,6 +17,11 @@ Grammar( "super", "in", "where", + "for", + "loop", + "while", + "if", + "match" ], tokens: [ "ERROR", diff --git a/src/parser/event_parser/grammar/items/mod.rs b/src/parser/event_parser/grammar/items/mod.rs index 0a50fffc11..4d87837354 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) { assert!(p.at(IDENT)); let m = p.start(); p.bump(); + if p.eat(COLON) { + loop { + let has_paren = p.eat(L_PAREN); + p.eat(QUESTION); + if p.at(FOR_KW) { + //TODO + } + if p.at(LIFETIME) { + p.bump(); + } else if paths::is_path_start(p) { + paths::type_path(p); + } else { + break; + } + if has_paren { + p.expect(R_PAREN); + } + if !p.eat(PLUS) { + break; + } + } + } + if p.at(EQ) { + types::type_ref(p) + } m.complete(p, TYPE_PARAM); - //TODO: bounds } } diff --git a/src/parser/event_parser/grammar/paths.rs b/src/parser/event_parser/grammar/paths.rs index a254ab05ed..bf3c8aedd0 100644 --- a/src/parser/event_parser/grammar/paths.rs +++ b/src/parser/event_parser/grammar/paths.rs @@ -1,10 +1,18 @@ use super::*; -pub(crate) fn is_path_start(p: &Parser) -> bool { +pub(super) fn is_path_start(p: &Parser) -> bool { AnyOf(&[IDENT, SELF_KW, SUPER_KW, COLONCOLON]).is_ahead(p) } -pub(crate) fn use_path(p: &mut Parser) { +pub(super) fn use_path(p: &mut Parser) { + path(p) +} + +pub(super) fn type_path(p: &mut Parser) { + path(p) +} + +fn path(p: &mut Parser) { if !is_path_start(p) { return; } @@ -24,6 +32,7 @@ pub(crate) fn use_path(p: &mut Parser) { } } + fn path_segment(p: &mut Parser, first: bool) { let segment = p.start(); if first { diff --git a/src/syntax_kinds.rs b/src/syntax_kinds.rs index 519326f48a..cd4c753a9b 100644 --- a/src/syntax_kinds.rs +++ b/src/syntax_kinds.rs @@ -23,6 +23,11 @@ pub enum SyntaxKind { SUPER_KW, IN_KW, WHERE_KW, + FOR_KW, + LOOP_KW, + WHILE_KW, + IF_KW, + MATCH_KW, ERROR, IDENT, UNDERSCORE, @@ -125,6 +130,11 @@ impl SyntaxKind { SUPER_KW => &SyntaxInfo { name: "SUPER_KW" }, IN_KW => &SyntaxInfo { name: "IN_KW" }, WHERE_KW => &SyntaxInfo { name: "WHERE_KW" }, + FOR_KW => &SyntaxInfo { name: "FOR_KW" }, + LOOP_KW => &SyntaxInfo { name: "LOOP_KW" }, + WHILE_KW => &SyntaxInfo { name: "WHILE_KW" }, + IF_KW => &SyntaxInfo { name: "IF_KW" }, + MATCH_KW => &SyntaxInfo { name: "MATCH_KW" }, ERROR => &SyntaxInfo { name: "ERROR" }, IDENT => &SyntaxInfo { name: "IDENT" }, UNDERSCORE => &SyntaxInfo { name: "UNDERSCORE" }, @@ -223,6 +233,11 @@ pub(crate) fn ident_to_keyword(ident: &str) -> Option { "super" => Some(SUPER_KW), "in" => Some(IN_KW), "where" => Some(WHERE_KW), + "for" => Some(FOR_KW), + "loop" => Some(LOOP_KW), + "while" => Some(WHILE_KW), + "if" => Some(IF_KW), + "match" => Some(MATCH_KW), _ => None, } } diff --git a/tests/data/lexer/0011_keywords.rs b/tests/data/lexer/0011_keywords.rs index c2c9e56674..02ca190891 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 301ee21e25..964e3475a3 100644 --- a/tests/data/lexer/0011_keywords.txt +++ b/tests/data/lexer/0011_keywords.txt @@ -31,4 +31,14 @@ WHITESPACE 1 " " IN_KW 2 "in" WHITESPACE 1 " " WHERE_KW 5 "where" +WHITESPACE 1 " " +FOR_KW 3 "for" +WHITESPACE 1 " " +LOOP_KW 4 "loop" +WHITESPACE 1 " " +WHILE_KW 5 "while" +WHITESPACE 1 " " +IF_KW 2 "if" +WHITESPACE 1 " " +MATCH_KW 5 "match" 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 ac07606957..c33113c6d7 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 @@ FILE@[0; 21) ERROR@[0; 3) err: `expected item` - IDENT@[0; 2) "if" + IF_KW@[0; 2) WHITESPACE@[2; 3) ERROR@[3; 10) err: `expected item` - IDENT@[3; 8) "match" + MATCH_KW@[3; 8) WHITESPACE@[8; 10) STRUCT_ITEM@[10; 21) 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 df6a952cd1..c6386fd73a 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) err: `expected item` L_CURLY@[20; 21) WHITESPACE@[21; 26) - IDENT@[26; 28) "if" + IF_KW@[26; 28) WHITESPACE@[28; 29) TRUE_KW@[29; 33) 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 0000000000..a1b9f00a47 --- /dev/null +++ b/tests/data/parser/ok/0020_type_param_bounds.rs @@ -0,0 +1,9 @@ +struct A; +struct B; +struct C; +struct D; +struct E; +struct F; +struct G; +struct H; +struct I; 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 0000000000..6f65d150ac --- /dev/null +++ b/tests/data/parser/ok/0020_type_param_bounds.txt @@ -0,0 +1,169 @@ +FILE@[0; 200) + STRUCT_ITEM@[0; 13) + STRUCT_KW@[0; 6) + WHITESPACE@[6; 7) + IDENT@[7; 8) "A" + TYPE_PARAM_LIST@[8; 11) + L_ANGLE@[8; 9) + TYPE_PARAM@[9; 10) + IDENT@[9; 10) "T" + R_ANGLE@[10; 11) + SEMI@[11; 12) + WHITESPACE@[12; 13) + STRUCT_ITEM@[13; 27) + STRUCT_KW@[13; 19) + WHITESPACE@[19; 20) + IDENT@[20; 21) "B" + TYPE_PARAM_LIST@[21; 25) + L_ANGLE@[21; 22) + TYPE_PARAM@[22; 24) + IDENT@[22; 23) "T" + COLON@[23; 24) + R_ANGLE@[24; 25) + SEMI@[25; 26) + WHITESPACE@[26; 27) + STRUCT_ITEM@[27; 44) + STRUCT_KW@[27; 33) + WHITESPACE@[33; 34) + IDENT@[34; 35) "C" + TYPE_PARAM_LIST@[35; 42) + L_ANGLE@[35; 36) + TYPE_PARAM@[36; 41) + IDENT@[36; 37) "T" + COLON@[37; 38) + WHITESPACE@[38; 39) + LIFETIME@[39; 41) "'a" + R_ANGLE@[41; 42) + SEMI@[42; 43) + WHITESPACE@[43; 44) + STRUCT_ITEM@[44; 64) + STRUCT_KW@[44; 50) + WHITESPACE@[50; 51) + IDENT@[51; 52) "D" + TYPE_PARAM_LIST@[52; 62) + L_ANGLE@[52; 53) + TYPE_PARAM@[53; 61) + IDENT@[53; 54) "T" + COLON@[54; 55) + WHITESPACE@[55; 56) + LIFETIME@[56; 58) "'a" + WHITESPACE@[58; 59) + PLUS@[59; 60) + WHITESPACE@[60; 61) + R_ANGLE@[61; 62) + SEMI@[62; 63) + WHITESPACE@[63; 64) + STRUCT_ITEM@[64; 87) + STRUCT_KW@[64; 70) + WHITESPACE@[70; 71) + IDENT@[71; 72) "E" + TYPE_PARAM_LIST@[72; 85) + L_ANGLE@[72; 73) + TYPE_PARAM@[73; 84) + IDENT@[73; 74) "T" + COLON@[74; 75) + WHITESPACE@[75; 76) + LIFETIME@[76; 78) "'a" + WHITESPACE@[78; 79) + PLUS@[79; 80) + WHITESPACE@[80; 81) + LIFETIME@[81; 83) "'d" + WHITESPACE@[83; 84) + R_ANGLE@[84; 85) + SEMI@[85; 86) + WHITESPACE@[86; 87) + STRUCT_ITEM@[87; 117) + STRUCT_KW@[87; 93) + WHITESPACE@[93; 94) + IDENT@[94; 95) "F" + TYPE_PARAM_LIST@[95; 115) + L_ANGLE@[95; 96) + TYPE_PARAM@[96; 114) + IDENT@[96; 97) "T" + COLON@[97; 98) + WHITESPACE@[98; 99) + LIFETIME@[99; 101) "'a" + WHITESPACE@[101; 102) + PLUS@[102; 103) + WHITESPACE@[103; 104) + LIFETIME@[104; 106) "'d" + WHITESPACE@[106; 107) + PLUS@[107; 108) + PATH@[108; 114) + PATH_SEGMENT@[108; 114) + WHITESPACE@[108; 109) + IDENT@[109; 114) "Clone" + R_ANGLE@[114; 115) + SEMI@[115; 116) + WHITESPACE@[116; 117) + STRUCT_ITEM@[117; 144) + STRUCT_KW@[117; 123) + WHITESPACE@[123; 124) + IDENT@[124; 125) "G" + TYPE_PARAM_LIST@[125; 142) + L_ANGLE@[125; 126) + TYPE_PARAM@[126; 141) + IDENT@[126; 127) "T" + COLON@[127; 128) + PATH@[128; 135) + PATH_SEGMENT@[128; 135) + WHITESPACE@[128; 129) + IDENT@[129; 134) "Clone" + WHITESPACE@[134; 135) + PLUS@[135; 136) + PATH@[136; 141) + PATH_SEGMENT@[136; 141) + WHITESPACE@[136; 137) + IDENT@[137; 141) "Copy" + R_ANGLE@[141; 142) + SEMI@[142; 143) + WHITESPACE@[143; 144) + STRUCT_ITEM@[144; 181) + STRUCT_KW@[144; 150) + WHITESPACE@[150; 151) + IDENT@[151; 152) "H" + TYPE_PARAM_LIST@[152; 179) + L_ANGLE@[152; 153) + TYPE_PARAM@[153; 178) + IDENT@[153; 154) "T" + COLON@[154; 155) + PATH@[155; 162) + PATH_SEGMENT@[155; 162) + WHITESPACE@[155; 156) + COLONCOLON@[156; 158) + IDENT@[158; 161) "Foo" + WHITESPACE@[161; 162) + PLUS@[162; 163) + PATH@[163; 174) + PATH@[163; 168) + PATH_SEGMENT@[163; 168) + WHITESPACE@[163; 164) + SELF_KW@[164; 168) + COLONCOLON@[168; 170) + PATH_SEGMENT@[170; 174) + IDENT@[170; 173) "Bar" + WHITESPACE@[173; 174) + PLUS@[174; 175) + WHITESPACE@[175; 176) + LIFETIME@[176; 178) "'a" + R_ANGLE@[178; 179) + SEMI@[179; 180) + WHITESPACE@[180; 181) + STRUCT_ITEM@[181; 200) + STRUCT_KW@[181; 187) + WHITESPACE@[187; 188) + IDENT@[188; 189) "I" + TYPE_PARAM_LIST@[189; 198) + L_ANGLE@[189; 190) + TYPE_PARAM@[190; 192) + IDENT@[190; 191) "T" + COLON@[191; 192) + COMMA@[192; 193) + TYPE_PARAM@[193; 196) + WHITESPACE@[193; 194) + IDENT@[194; 195) "U" + COLON@[195; 196) + COMMA@[196; 197) + R_ANGLE@[197; 198) + SEMI@[198; 199) + WHITESPACE@[199; 200) From 7a02097b717c6f7055a92c52dca65c374b06f057 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 30 Jan 2018 22:56:13 +0300 Subject: [PATCH 2/2] Formatting --- src/parser/event_parser/grammar/paths.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/parser/event_parser/grammar/paths.rs b/src/parser/event_parser/grammar/paths.rs index bf3c8aedd0..4c0d2c8b4e 100644 --- a/src/parser/event_parser/grammar/paths.rs +++ b/src/parser/event_parser/grammar/paths.rs @@ -32,7 +32,6 @@ fn path(p: &mut Parser) { } } - fn path_segment(p: &mut Parser, first: bool) { let segment = p.start(); if first {