From 7edab6ae6b4c5d0c411e88f10e923b91dca31de3 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 24 Aug 2018 19:27:30 +0300 Subject: nodes for blocks --- crates/libsyntax2/src/grammar/expressions/atom.rs | 73 ++++++---------------- crates/libsyntax2/src/grammar/expressions/mod.rs | 67 +++++++++++++++++--- crates/libsyntax2/src/grammar/items/mod.rs | 26 +++++--- crates/libsyntax2/src/grammar/items/structs.rs | 75 ++++++++++++++--------- crates/libsyntax2/src/grammar/items/traits.rs | 54 +++++++++++----- crates/libsyntax2/src/grammar/items/use_item.rs | 8 ++- crates/libsyntax2/src/grammar/mod.rs | 25 ++++---- crates/libsyntax2/src/grammar/patterns.rs | 8 ++- 8 files changed, 203 insertions(+), 133 deletions(-) (limited to 'crates/libsyntax2/src/grammar') diff --git a/crates/libsyntax2/src/grammar/expressions/atom.rs b/crates/libsyntax2/src/grammar/expressions/atom.rs index 9d98340af..417366026 100644 --- a/crates/libsyntax2/src/grammar/expressions/atom.rs +++ b/crates/libsyntax2/src/grammar/expressions/atom.rs @@ -148,7 +148,11 @@ fn lambda_expr(p: &mut Parser) -> CompletedMarker { p.eat(MOVE_KW); params::param_list_opt_types(p); if opt_fn_ret_type(p) { - block(p); + if p.at(L_CURLY) { + block(p); + } else { + p.error("expected a block"); + } } else { expr(p); } @@ -254,6 +258,17 @@ fn match_expr(p: &mut Parser) -> CompletedMarker { let m = p.start(); p.bump(); expr_no_struct(p); + if p.at(L_CURLY) { + match_arm_list(p); + } else { + p.error("expected `{`") + } + m.complete(p, MATCH_EXPR) +} + +fn match_arm_list(p: &mut Parser) { + assert!(p.at(L_CURLY)); + let m = p.start(); p.eat(L_CURLY); while !p.at(EOF) && !p.at(R_CURLY) { // test match_arms_commas @@ -271,7 +286,7 @@ fn match_expr(p: &mut Parser) -> CompletedMarker { } } p.expect(R_CURLY); - m.complete(p, MATCH_EXPR) + m.complete(p, MATCH_ARM_LIST); } // test match_arm @@ -307,62 +322,10 @@ pub(super) fn block_expr(p: &mut Parser) -> CompletedMarker { assert!(p.at(L_CURLY) || p.at(UNSAFE_KW) && p.nth(1) == L_CURLY); let m = p.start(); p.eat(UNSAFE_KW); - p.bump(); - while !p.at(EOF) && !p.at(R_CURLY) { - match p.current() { - LET_KW => let_stmt(p), - _ => { - // test block_items - // fn a() { fn b() {} } - let m = p.start(); - match items::maybe_item(p, items::ItemFlavor::Mod) { - items::MaybeItem::Item(kind) => { - m.complete(p, kind); - } - items::MaybeItem::Modifiers => { - m.abandon(p); - p.error("expected an item"); - } - // test pub_expr - // fn foo() { pub 92; } //FIXME - items::MaybeItem::None => { - let is_blocklike = expressions::expr_stmt(p) == BlockLike::Block; - if p.eat(SEMI) || (is_blocklike && !p.at(R_CURLY)) { - m.complete(p, EXPR_STMT); - } else { - m.abandon(p); - } - } - } - } - } - } - p.expect(R_CURLY); + block(p); m.complete(p, BLOCK_EXPR) } -// test let_stmt; -// fn foo() { -// let a; -// let b: i32; -// let c = 92; -// let d: i32 = 92; -// } -fn let_stmt(p: &mut Parser) { - assert!(p.at(LET_KW)); - let m = p.start(); - p.bump(); - patterns::pattern(p); - if p.at(COLON) { - types::ascription(p); - } - if p.eat(EQ) { - expressions::expr(p); - } - p.expect(SEMI); - m.complete(p, LET_STMT); -} - // test return_expr // fn foo() { // return; diff --git a/crates/libsyntax2/src/grammar/expressions/mod.rs b/crates/libsyntax2/src/grammar/expressions/mod.rs index 9ce0c1f8f..e133c1d9b 100644 --- a/crates/libsyntax2/src/grammar/expressions/mod.rs +++ b/crates/libsyntax2/src/grammar/expressions/mod.rs @@ -26,11 +26,62 @@ fn expr_no_struct(p: &mut Parser) { // fn c() { 1; 2; } // fn d() { 1; 2 } pub(super) fn block(p: &mut Parser) { - if !p.at(L_CURLY) { - p.error("expected block"); - return; + assert!(p.at(L_CURLY)); + let m = p.start(); + p.bump(); + while !p.at(EOF) && !p.at(R_CURLY) { + match p.current() { + LET_KW => let_stmt(p), + _ => { + // test block_items + // fn a() { fn b() {} } + let m = p.start(); + match items::maybe_item(p, items::ItemFlavor::Mod) { + items::MaybeItem::Item(kind) => { + m.complete(p, kind); + } + items::MaybeItem::Modifiers => { + m.abandon(p); + p.error("expected an item"); + } + // test pub_expr + // fn foo() { pub 92; } //FIXME + items::MaybeItem::None => { + let is_blocklike = expressions::expr_stmt(p) == BlockLike::Block; + if p.eat(SEMI) || (is_blocklike && !p.at(R_CURLY)) { + m.complete(p, EXPR_STMT); + } else { + m.abandon(p); + } + } + } + } + } + } + p.expect(R_CURLY); + m.complete(p, BLOCK); + + // test let_stmt; + // fn foo() { + // let a; + // let b: i32; + // let c = 92; + // let d: i32 = 92; + // } + fn let_stmt(p: &mut Parser) { + assert!(p.at(LET_KW)); + let m = p.start(); + p.bump(); + patterns::pattern(p); + if p.at(COLON) { + types::ascription(p); + } + if p.eat(EQ) { + expressions::expr(p); + } + p.expect(SEMI); + m.complete(p, LET_STMT); } - atom::block_expr(p); } #[derive(Clone, Copy)] @@ -339,7 +390,7 @@ fn path_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker { paths::expr_path(p); match p.current() { L_CURLY if !r.forbid_structs => { - struct_lit(p); + named_field_list(p); m.complete(p, STRUCT_LIT) } EXCL => { @@ -356,8 +407,9 @@ fn path_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker { // S { x, y: 32, }; // S { x, y: 32, ..Default::default() }; // } -fn struct_lit(p: &mut Parser) { +fn named_field_list(p: &mut Parser) { assert!(p.at(L_CURLY)); + let m = p.start(); p.bump(); while !p.at(EOF) && !p.at(R_CURLY) { match p.current() { @@ -367,7 +419,7 @@ fn struct_lit(p: &mut Parser) { if p.eat(COLON) { expr(p); } - m.complete(p, STRUCT_LIT_FIELD); + m.complete(p, NAMED_FIELD); } DOTDOT => { p.bump(); @@ -380,4 +432,5 @@ fn struct_lit(p: &mut Parser) { } } p.expect(R_CURLY); + m.complete(p, NAMED_FIELD_LIST); } diff --git a/crates/libsyntax2/src/grammar/items/mod.rs b/crates/libsyntax2/src/grammar/items/mod.rs index 18b681ee2..d236fb506 100644 --- a/crates/libsyntax2/src/grammar/items/mod.rs +++ b/crates/libsyntax2/src/grammar/items/mod.rs @@ -194,8 +194,8 @@ fn items_without_modifiers(p: &mut Parser) -> Option { // extern {} EXTERN_KW if la == L_CURLY || ((la == STRING || la == RAW_STRING) && p.nth(2) == L_CURLY) => { abi(p); - extern_block(p); - EXTERN_BLOCK_EXPR + extern_item_list(p); + EXTERN_BLOCK } _ => return None, }; @@ -212,10 +212,12 @@ fn extern_crate_item(p: &mut Parser) { p.expect(SEMI); } -fn extern_block(p: &mut Parser) { +fn extern_item_list(p: &mut Parser) { assert!(p.at(L_CURLY)); + let m = p.start(); p.bump(); p.expect(R_CURLY); + m.complete(p, EXTERN_ITEM_LIST); } fn function(p: &mut Parser, flavor: ItemFlavor) { @@ -284,14 +286,22 @@ fn mod_item(p: &mut Parser) { p.bump(); name(p); - if !p.eat(SEMI) { - if p.expect(L_CURLY) { - mod_contents(p, true); - p.expect(R_CURLY); - } + if p.at(L_CURLY) { + mod_item_list(p); + } else if !p.eat(SEMI) { + p.error("expected `;` or `{`"); } } +fn mod_item_list(p: &mut Parser) { + assert!(p.at(L_CURLY)); + let m = p.start(); + p.bump(); + mod_contents(p, true); + p.expect(R_CURLY); + m.complete(p, ITEM_LIST); +} + fn macro_call(p: &mut Parser) -> BlockLike { assert!(paths::is_path_start(p)); paths::use_path(p); diff --git a/crates/libsyntax2/src/grammar/items/structs.rs b/crates/libsyntax2/src/grammar/items/structs.rs index cde9d0ae6..ca027d718 100644 --- a/crates/libsyntax2/src/grammar/items/structs.rs +++ b/crates/libsyntax2/src/grammar/items/structs.rs @@ -14,7 +14,7 @@ pub(super) fn struct_def(p: &mut Parser) { p.bump(); return; } - L_CURLY => named_fields(p), + L_CURLY => named_field_def_list(p), _ => { //TODO: special case `(` error message p.error("expected `;` or `{`"); @@ -26,9 +26,9 @@ pub(super) fn struct_def(p: &mut Parser) { p.bump(); return; } - L_CURLY => named_fields(p), + L_CURLY => named_field_def_list(p), L_PAREN => { - pos_fields(p); + pos_field_list(p); p.expect(SEMI); } _ => { @@ -44,46 +44,58 @@ pub(super) fn enum_def(p: &mut Parser) { name(p); type_params::opt_type_param_list(p); type_params::opt_where_clause(p); - if p.expect(L_CURLY) { - while !p.at(EOF) && !p.at(R_CURLY) { - let var = p.start(); - attributes::outer_attributes(p); - if p.at(IDENT) { - name(p); - match p.current() { - L_CURLY => named_fields(p), - L_PAREN => pos_fields(p), - EQ => { - p.bump(); - expressions::expr(p); - } - _ => (), + if p.at(L_CURLY) { + enum_variant_list(p); + } else { + p.error("expected `{`") + } +} + +fn enum_variant_list(p: &mut Parser) { + assert!(p.at(L_CURLY)); + let m = p.start(); + p.bump(); + while !p.at(EOF) && !p.at(R_CURLY) { + let var = p.start(); + attributes::outer_attributes(p); + if p.at(IDENT) { + name(p); + match p.current() { + L_CURLY => named_field_def_list(p), + L_PAREN => pos_field_list(p), + EQ => { + p.bump(); + expressions::expr(p); } - var.complete(p, ENUM_VARIANT); - } else { - var.abandon(p); - p.err_and_bump("expected enum variant"); - } - if !p.at(R_CURLY) { - p.expect(COMMA); + _ => (), } + var.complete(p, ENUM_VARIANT); + } else { + var.abandon(p); + p.err_and_bump("expected enum variant"); + } + if !p.at(R_CURLY) { + p.expect(COMMA); } - p.expect(R_CURLY); } + p.expect(R_CURLY); + m.complete(p, ENUM_VARIANT_LIST); } -fn named_fields(p: &mut Parser) { +fn named_field_def_list(p: &mut Parser) { assert!(p.at(L_CURLY)); + let m = p.start(); p.bump(); while !p.at(R_CURLY) && !p.at(EOF) { - named_field(p); + named_field_def(p); if !p.at(R_CURLY) { p.expect(COMMA); } } p.expect(R_CURLY); + m.complete(p, NAMED_FIELD_DEF_LIST); - fn named_field(p: &mut Parser) { + fn named_field_def(p: &mut Parser) { let m = p.start(); // test field_attrs // struct S { @@ -96,7 +108,7 @@ fn named_fields(p: &mut Parser) { name(p); p.expect(COLON); types::type_(p); - m.complete(p, NAMED_FIELD); + m.complete(p, NAMED_FIELD_DEF); } else { m.abandon(p); p.err_and_bump("expected field declaration"); @@ -104,7 +116,9 @@ fn named_fields(p: &mut Parser) { } } -fn pos_fields(p: &mut Parser) { +fn pos_field_list(p: &mut Parser) { + assert!(p.at(L_PAREN)); + let m = p.start(); if !p.expect(L_PAREN) { return; } @@ -119,4 +133,5 @@ fn pos_fields(p: &mut Parser) { } } p.expect(R_PAREN); + m.complete(p, POS_FIELD_LIST); } diff --git a/crates/libsyntax2/src/grammar/items/traits.rs b/crates/libsyntax2/src/grammar/items/traits.rs index 73ecd4bef..3853ccaab 100644 --- a/crates/libsyntax2/src/grammar/items/traits.rs +++ b/crates/libsyntax2/src/grammar/items/traits.rs @@ -11,18 +11,29 @@ pub(super) fn trait_def(p: &mut Parser) { type_params::bounds(p); } type_params::opt_where_clause(p); - p.expect(L_CURLY); - // test trait_item_items - // impl F { - // type A: Clone; - // const B: i32; - // fn foo() {} - // fn bar(&self); - // } + if p.at(L_CURLY) { + trait_item_list(p); + } else { + p.error("expected `{`"); + } +} + +// test trait_item_list +// impl F { +// type A: Clone; +// const B: i32; +// fn foo() {} +// fn bar(&self); +// } +fn trait_item_list(p: &mut Parser) { + assert!(p.at(L_CURLY)); + let m = p.start(); + p.bump(); while !p.at(EOF) && !p.at(R_CURLY) { item_or_macro(p, true, ItemFlavor::Trait); } p.expect(R_CURLY); + m.complete(p, ITEM_LIST); } // test impl_item @@ -45,19 +56,30 @@ pub(super) fn impl_item(p: &mut Parser) { types::type_(p); } type_params::opt_where_clause(p); - p.expect(L_CURLY); + if p.at(L_CURLY) { + impl_item_list(p); + } else { + p.error("expected `{`"); + } +} + +// test impl_item_list +// impl F { +// type A = i32; +// const B: i32 = 92; +// fn foo() {} +// fn bar(&self) {} +// } +fn impl_item_list(p: &mut Parser) { + assert!(p.at(L_CURLY)); + let m = p.start(); + p.bump(); - // test impl_item_items - // impl F { - // type A = i32; - // const B: i32 = 92; - // fn foo() {} - // fn bar(&self) {} - // } while !p.at(EOF) && !p.at(R_CURLY) { item_or_macro(p, true, ItemFlavor::Mod); } p.expect(R_CURLY); + m.complete(p, ITEM_LIST); } fn choose_type_params_over_qpath(p: &Parser) -> bool { diff --git a/crates/libsyntax2/src/grammar/items/use_item.rs b/crates/libsyntax2/src/grammar/items/use_item.rs index 3da40a629..2fbf2234a 100644 --- a/crates/libsyntax2/src/grammar/items/use_item.rs +++ b/crates/libsyntax2/src/grammar/items/use_item.rs @@ -20,7 +20,7 @@ fn use_tree(p: &mut Parser) { if p.at(COLONCOLON) { p.bump(); } - nested_trees(p); + use_tree_list(p); } _ if paths::is_path_start(p) => { paths::use_path(p); @@ -34,7 +34,7 @@ fn use_tree(p: &mut Parser) { STAR => { p.bump(); } - L_CURLY => nested_trees(p), + L_CURLY => use_tree_list(p), _ => { // is this unreachable? p.error("expected `{` or `*`"); @@ -53,8 +53,9 @@ fn use_tree(p: &mut Parser) { m.complete(p, USE_TREE); } -fn nested_trees(p: &mut Parser) { +fn use_tree_list(p: &mut Parser) { assert!(p.at(L_CURLY)); + let m = p.start(); p.bump(); while !p.at(EOF) && !p.at(R_CURLY) { use_tree(p); @@ -63,4 +64,5 @@ fn nested_trees(p: &mut Parser) { } } p.expect(R_CURLY); + m.complete(p, USE_TREE_LIST); } diff --git a/crates/libsyntax2/src/grammar/mod.rs b/crates/libsyntax2/src/grammar/mod.rs index 25887921b..0f118f12d 100644 --- a/crates/libsyntax2/src/grammar/mod.rs +++ b/crates/libsyntax2/src/grammar/mod.rs @@ -144,18 +144,21 @@ fn name_ref(p: &mut Parser) { } fn error_block(p: &mut Parser, message: &str) { - assert!(p.at(L_CURLY)); - let err = p.start(); - p.error(message); - p.bump(); - let mut level: u32 = 1; - while level > 0 && !p.at(EOF) { - match p.current() { - L_CURLY => level += 1, - R_CURLY => level -= 1, - _ => (), + go(p, Some(message)); + fn go(p: &mut Parser, message: Option<&str>) { + assert!(p.at(L_CURLY)); + let m = p.start(); + if let Some(message) = message { + p.error(message); } p.bump(); + while !p.at(EOF) && !p.at(R_CURLY) { + match p.current() { + L_CURLY => go(p, None), + _ => p.bump(), + } + } + p.eat(R_CURLY); + m.complete(p, ERROR); } - err.complete(p, ERROR); } diff --git a/crates/libsyntax2/src/grammar/patterns.rs b/crates/libsyntax2/src/grammar/patterns.rs index 71a1d5445..7ddbfa318 100644 --- a/crates/libsyntax2/src/grammar/patterns.rs +++ b/crates/libsyntax2/src/grammar/patterns.rs @@ -69,7 +69,7 @@ fn path_pat(p: &mut Parser) -> CompletedMarker { TUPLE_STRUCT_PAT } L_CURLY => { - struct_pat_fields(p); + field_pat_list(p); STRUCT_PAT } _ => PATH_PAT @@ -99,15 +99,16 @@ fn tuple_pat_fields(p: &mut Parser) { p.expect(R_PAREN); } -// test struct_pat_fields +// test field_pat_list // fn foo() { // let S {} = (); // let S { f, ref mut g } = (); // let S { h: _, ..} = (); // let S { h: _, } = (); // } -fn struct_pat_fields(p: &mut Parser) { +fn field_pat_list(p: &mut Parser) { assert!(p.at(L_CURLY)); + let m = p.start(); p.bump(); while !p.at(EOF) && !p.at(R_CURLY) { match p.current() { @@ -126,6 +127,7 @@ fn struct_pat_fields(p: &mut Parser) { } } p.expect(R_CURLY); + m.complete(p, FIELD_PAT_LIST); } // test placeholder_pat -- cgit v1.2.3