From 7912189ec304b28c4df0030b5282cf3d21074154 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 31 Jul 2018 23:38:19 +0300 Subject: reorganize --- src/parser/grammar/attributes.rs | 79 ---------- src/parser/grammar/expressions.rs | 284 ---------------------------------- src/parser/grammar/items/consts.rs | 20 --- src/parser/grammar/items/mod.rs | 290 ----------------------------------- src/parser/grammar/items/structs.rs | 116 -------------- src/parser/grammar/items/traits.rs | 77 ---------- src/parser/grammar/items/use_item.rs | 66 -------- src/parser/grammar/mod.rs | 144 ----------------- src/parser/grammar/params.rs | 71 --------- src/parser/grammar/paths.rs | 77 ---------- src/parser/grammar/patterns.rs | 53 ------- src/parser/grammar/type_args.rs | 48 ------ src/parser/grammar/type_params.rs | 96 ------------ src/parser/grammar/types.rs | 207 ------------------------- 14 files changed, 1628 deletions(-) delete mode 100644 src/parser/grammar/attributes.rs delete mode 100644 src/parser/grammar/expressions.rs delete mode 100644 src/parser/grammar/items/consts.rs delete mode 100644 src/parser/grammar/items/mod.rs delete mode 100644 src/parser/grammar/items/structs.rs delete mode 100644 src/parser/grammar/items/traits.rs delete mode 100644 src/parser/grammar/items/use_item.rs delete mode 100644 src/parser/grammar/mod.rs delete mode 100644 src/parser/grammar/params.rs delete mode 100644 src/parser/grammar/paths.rs delete mode 100644 src/parser/grammar/patterns.rs delete mode 100644 src/parser/grammar/type_args.rs delete mode 100644 src/parser/grammar/type_params.rs delete mode 100644 src/parser/grammar/types.rs (limited to 'src/parser/grammar') diff --git a/src/parser/grammar/attributes.rs b/src/parser/grammar/attributes.rs deleted file mode 100644 index c411d4d7f..000000000 --- a/src/parser/grammar/attributes.rs +++ /dev/null @@ -1,79 +0,0 @@ -use super::*; - -pub(super) fn inner_attributes(p: &mut Parser) { - while p.current() == POUND && p.nth(1) == EXCL { - attribute(p, true) - } -} - -pub(super) fn outer_attributes(p: &mut Parser) { - while p.at(POUND) { - attribute(p, false) - } -} - -fn attribute(p: &mut Parser, inner: bool) { - let attr = p.start(); - assert!(p.at(POUND)); - p.bump(); - - if inner { - assert!(p.at(EXCL)); - p.bump(); - } - - if p.expect(L_BRACK) { - meta_item(p); - p.expect(R_BRACK); - } - attr.complete(p, ATTR); -} - -fn meta_item(p: &mut Parser) { - if p.at(IDENT) { - let meta_item = p.start(); - p.bump(); - match p.current() { - EQ => { - p.bump(); - if expressions::literal(p).is_none() { - p.error("expected literal"); - } - } - L_PAREN => meta_item_arg_list(p), - _ => (), - } - meta_item.complete(p, META_ITEM); - } else { - p.error("expected attribute value"); - } -} - -fn meta_item_arg_list(p: &mut Parser) { - assert!(p.at(L_PAREN)); - p.bump(); - loop { - match p.current() { - EOF | R_PAREN => break, - IDENT => meta_item(p), - c => if expressions::literal(p).is_none() { - let message = "expected attribute"; - - if items::ITEM_FIRST.contains(c) { - p.error(message); - return; - } - - let err = p.start(); - p.error(message); - p.bump(); - err.complete(p, ERROR); - continue; - }, - } - if !p.at(R_PAREN) { - p.expect(COMMA); - } - } - p.expect(R_PAREN); -} diff --git a/src/parser/grammar/expressions.rs b/src/parser/grammar/expressions.rs deleted file mode 100644 index 06f9105c6..000000000 --- a/src/parser/grammar/expressions.rs +++ /dev/null @@ -1,284 +0,0 @@ -use super::*; - -// test expr_literals -// fn foo() { -// let _ = true; -// let _ = false; -// let _ = 1; -// let _ = 2.0; -// let _ = b'a'; -// let _ = 'b'; -// let _ = "c"; -// let _ = r"d"; -// let _ = b"e"; -// let _ = br"f"; -// } -pub(super) fn literal(p: &mut Parser) -> Option { - match p.current() { - TRUE_KW | FALSE_KW | INT_NUMBER | FLOAT_NUMBER | BYTE | CHAR | STRING | RAW_STRING - | BYTE_STRING | RAW_BYTE_STRING => { - let m = p.start(); - p.bump(); - Some(m.complete(p, LITERAL)) - } - _ => None, - } -} - -pub(super) fn expr(p: &mut Parser) { - let mut lhs = match prefix_expr(p) { - Some(lhs) => lhs, - None => return, - }; - - loop { - lhs = match p.current() { - L_PAREN => call_expr(p, lhs), - DOT if p.nth(1) == IDENT => if p.nth(2) == L_PAREN { - method_call_expr(p, lhs) - } else { - field_expr(p, lhs) - }, - _ => break, - } - } -} - -// test block -// fn a() {} -// fn b() { let _ = 1; } -// fn c() { 1; 2; } -// fn d() { 1; 2 } -pub(super) fn block(p: &mut Parser) { - if !p.at(L_CURLY) { - p.error("expected block"); - } - let m = p.start(); - p.bump(); - while !p.at(EOF) && !p.at(R_CURLY) { - match p.current() { - LET_KW => let_stmt(p), - c => { - // test block_items - // fn a() { fn b() {} } - if items::ITEM_FIRST.contains(c) { - items::item(p) - } else { - let expr_stmt = p.start(); - expressions::expr(p); - if p.eat(SEMI) { - expr_stmt.complete(p, EXPR_STMT); - } else { - expr_stmt.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); -} - -fn prefix_expr(p: &mut Parser) -> Option { - match p.current() { - AMPERSAND => Some(ref_expr(p)), - STAR => Some(deref_expr(p)), - _ => atom_expr(p), - } -} - -// test ref_expr -// fn foo() { -// let _ = &1; -// let _ = &mut &f(); -// } -fn ref_expr(p: &mut Parser) -> CompletedMarker { - assert!(p.at(AMPERSAND)); - let m = p.start(); - p.bump(); - p.eat(MUT_KW); - expr(p); - m.complete(p, REF_EXPR) -} - -// test deref_expr -// fn foo() { -// **&1; -// } -fn deref_expr(p: &mut Parser) -> CompletedMarker { - assert!(p.at(STAR)); - let m = p.start(); - p.bump(); - expr(p); - m.complete(p, DEREF_EXPR) -} - -fn atom_expr(p: &mut Parser) -> Option { - match literal(p) { - Some(m) => return Some(m), - None => (), - } - if paths::is_path_start(p) { - return Some(path_expr(p)); - } - - match p.current() { - L_PAREN => Some(tuple_expr(p)), - PIPE => Some(lambda_expr(p)), - _ => { - p.err_and_bump("expected expression"); - None - } - } -} - -fn tuple_expr(p: &mut Parser) -> CompletedMarker { - assert!(p.at(L_PAREN)); - let m = p.start(); - p.expect(L_PAREN); - p.expect(R_PAREN); - m.complete(p, TUPLE_EXPR) -} - -// test lambda_expr -// fn foo() { -// || (); -// || -> i32 { 92 }; -// |x| x; -// |x: i32,| x; -// } -fn lambda_expr(p: &mut Parser) -> CompletedMarker { - assert!(p.at(PIPE)); - let m = p.start(); - params::param_list_opt_types(p); - if fn_ret_type(p) { - block(p); - } else { - expr(p) - } - m.complete(p, LAMBDA_EXPR) -} - -// test call_expr -// fn foo() { -// let _ = f(); -// let _ = f()(1)(1, 2,); -// } -fn call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { - assert!(p.at(L_PAREN)); - let m = lhs.precede(p); - arg_list(p); - m.complete(p, CALL_EXPR) -} - -// test method_call_expr -// fn foo() { -// x.foo(); -// y.bar(1, 2,); -// } -fn method_call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { - assert!(p.at(DOT) && p.nth(1) == IDENT && p.nth(2) == L_PAREN); - let m = lhs.precede(p); - p.bump(); - p.bump(); - arg_list(p); - m.complete(p, METHOD_CALL_EXPR) -} - -// test field_expr -// fn foo() { -// x.foo.bar; -// } -fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { - assert!(p.at(DOT) && p.nth(1) == IDENT); - let m = lhs.precede(p); - p.bump(); - p.bump(); - m.complete(p, FIELD_EXPR) -} - -fn arg_list(p: &mut Parser) { - assert!(p.at(L_PAREN)); - let m = p.start(); - p.bump(); - while !p.at(R_PAREN) && !p.at(EOF) { - expr(p); - if !p.at(R_PAREN) && !p.expect(COMMA) { - break; - } - } - p.eat(R_PAREN); - m.complete(p, ARG_LIST); -} - -// test path_expr -// fn foo() { -// let _ = a; -// let _ = a::b; -// let _ = ::a::; -// } -fn path_expr(p: &mut Parser) -> CompletedMarker { - assert!(paths::is_path_start(p)); - let m = p.start(); - paths::expr_path(p); - if p.at(L_CURLY) { - struct_lit(p); - m.complete(p, STRUCT_LIT) - } else { - m.complete(p, PATH_EXPR) - } -} - -// test struct_lit -// fn foo() { -// S {}; -// S { x, y: 32, }; -// S { x, y: 32, ..Default::default() }; -// } -fn struct_lit(p: &mut Parser) { - assert!(p.at(L_CURLY)); - p.bump(); - while !p.at(EOF) && !p.at(R_CURLY) { - match p.current() { - IDENT => { - let m = p.start(); - name_ref(p); - if p.eat(COLON) { - expr(p); - } - m.complete(p, STRUCT_LIT_FIELD); - } - DOTDOT => { - p.bump(); - expr(p); - } - _ => p.err_and_bump("expected identifier"), - } - if !p.at(R_CURLY) { - p.expect(COMMA); - } - } - p.expect(R_CURLY); -} diff --git a/src/parser/grammar/items/consts.rs b/src/parser/grammar/items/consts.rs deleted file mode 100644 index ca26a7814..000000000 --- a/src/parser/grammar/items/consts.rs +++ /dev/null @@ -1,20 +0,0 @@ -use super::*; - -pub(super) fn static_item(p: &mut Parser) { - const_or_static(p, STATIC_KW) -} - -pub(super) fn const_item(p: &mut Parser) { - const_or_static(p, CONST_KW) -} - -fn const_or_static(p: &mut Parser, kw: SyntaxKind) { - assert!(p.at(kw)); - p.bump(); - p.eat(MUT_KW); // TODO: validator to forbid const mut - name(p); - types::ascription(p); - p.expect(EQ); - expressions::expr(p); - p.expect(SEMI); -} diff --git a/src/parser/grammar/items/mod.rs b/src/parser/grammar/items/mod.rs deleted file mode 100644 index d5f75f13d..000000000 --- a/src/parser/grammar/items/mod.rs +++ /dev/null @@ -1,290 +0,0 @@ -use super::*; - -mod consts; -mod structs; -mod traits; -mod use_item; - -pub(super) fn mod_contents(p: &mut Parser, stop_on_r_curly: bool) { - attributes::inner_attributes(p); - while !p.at(EOF) && !(stop_on_r_curly && p.at(R_CURLY)) { - item(p); - } -} - -pub(super) const ITEM_FIRST: TokenSet = - token_set![EXTERN_KW, MOD_KW, USE_KW, STRUCT_KW, ENUM_KW, FN_KW, PUB_KW, POUND]; - -pub(super) fn item(p: &mut Parser) { - let item = p.start(); - attributes::outer_attributes(p); - visibility(p); - let la = p.nth(1); - let item_kind = match p.current() { - USE_KW => { - use_item::use_item(p); - USE_ITEM - } - // test extern_crate - // extern crate foo; - EXTERN_KW if la == CRATE_KW => { - extern_crate_item(p); - EXTERN_CRATE_ITEM - } - EXTERN_KW => { - abi(p); - match p.current() { - // test extern_fn - // extern fn foo() {} - FN_KW => { - fn_item(p); - FN_ITEM - } - // test extern_block - // extern {} - L_CURLY => { - extern_block(p); - EXTERN_BLOCK - } - // test extern_struct - // extern struct Foo; - _ => { - item.abandon(p); - p.error("expected `fn` or `{`"); - return; - } - } - } - STATIC_KW => { - consts::static_item(p); - STATIC_ITEM - } - CONST_KW => match p.nth(1) { - // test const_fn - // const fn foo() {} - FN_KW => { - p.bump(); - fn_item(p); - FN_ITEM - } - // test const_unsafe_fn - // const unsafe fn foo() {} - UNSAFE_KW if p.nth(2) == FN_KW => { - p.bump(); - p.bump(); - fn_item(p); - FN_ITEM - } - _ => { - consts::const_item(p); - CONST_ITEM - } - }, - UNSAFE_KW => { - p.bump(); - let la = p.nth(1); - match p.current() { - // test unsafe_trait - // unsafe trait T {} - TRAIT_KW => { - traits::trait_item(p); - TRAIT_ITEM - } - - // test unsafe_auto_trait - // unsafe auto trait T {} - IDENT if p.at_contextual_kw("auto") && la == TRAIT_KW => { - p.bump_remap(AUTO_KW); - traits::trait_item(p); - TRAIT_ITEM - } - - // test unsafe_impl - // unsafe impl Foo {} - IMPL_KW => { - traits::impl_item(p); - IMPL_ITEM - } - - // test unsafe_default_impl - // unsafe default impl Foo {} - IDENT if p.at_contextual_kw("default") && la == IMPL_KW => { - p.bump_remap(DEFAULT_KW); - traits::impl_item(p); - IMPL_ITEM - } - - // test unsafe_extern_fn - // unsafe extern "C" fn foo() {} - EXTERN_KW => { - abi(p); - if !p.at(FN_KW) { - item.abandon(p); - p.error("expected function"); - return; - } - fn_item(p); - FN_ITEM - } - - // test unsafe_fn - // unsafe fn foo() {} - FN_KW => { - fn_item(p); - FN_ITEM - } - - t => { - item.abandon(p); - let message = "expected `trait`, `impl` or `fn`"; - - // test unsafe_block_in_mod - // fn foo(){} unsafe { } fn bar(){} - if t == L_CURLY { - error_block(p, message); - } else { - p.error(message); - } - return; - } - } - } - TRAIT_KW => { - traits::trait_item(p); - TRAIT_ITEM - } - // test auto_trait - // auto trait T {} - IDENT if p.at_contextual_kw("auto") && la == TRAIT_KW => { - p.bump_remap(AUTO_KW); - traits::trait_item(p); - TRAIT_ITEM - } - IMPL_KW => { - traits::impl_item(p); - IMPL_ITEM - } - // test default_impl - // default impl Foo {} - IDENT if p.at_contextual_kw("default") && la == IMPL_KW => { - p.bump_remap(DEFAULT_KW); - traits::impl_item(p); - IMPL_ITEM - } - - FN_KW => { - fn_item(p); - FN_ITEM - } - TYPE_KW => { - type_item(p); - TYPE_ITEM - } - MOD_KW => { - mod_item(p); - MOD_ITEM - } - STRUCT_KW => { - structs::struct_item(p); - STRUCT_ITEM - } - ENUM_KW => { - structs::enum_item(p); - ENUM_ITEM - } - L_CURLY => { - item.abandon(p); - error_block(p, "expected item"); - return; - } - err_token => { - item.abandon(p); - let message = if err_token == SEMI { - //TODO: if the item is incomplete, this message is misleading - "expected item, found `;`\n\ - consider removing this semicolon" - } else { - "expected item" - }; - p.err_and_bump(message); - return; - } - }; - item.complete(p, item_kind); -} - -fn extern_crate_item(p: &mut Parser) { - assert!(p.at(EXTERN_KW)); - p.bump(); - assert!(p.at(CRATE_KW)); - p.bump(); - name(p); - alias(p); - p.expect(SEMI); -} - -fn extern_block(p: &mut Parser) { - assert!(p.at(L_CURLY)); - p.bump(); - p.expect(R_CURLY); -} - -fn fn_item(p: &mut Parser) { - assert!(p.at(FN_KW)); - p.bump(); - - name(p); - // test fn_item_type_params - // fn foo(){} - type_params::type_param_list(p); - - if p.at(L_PAREN) { - params::param_list(p); - } else { - p.error("expected function arguments"); - } - // test fn_item_ret_type - // fn foo() {} - // fn bar() -> () {} - fn_ret_type(p); - - // test fn_item_where_clause - // fn foo() where T: Copy {} - type_params::where_clause(p); - - expressions::block(p); -} - -// test type_item -// type Foo = Bar; -fn type_item(p: &mut Parser) { - assert!(p.at(TYPE_KW)); - p.bump(); - - name(p); - - // test type_item_type_params - // type Result = (); - type_params::type_param_list(p); - - // test type_item_where_clause - // type Foo where Foo: Copy = (); - type_params::where_clause(p); - - p.expect(EQ); - types::type_(p); - p.expect(SEMI); -} - -fn mod_item(p: &mut Parser) { - assert!(p.at(MOD_KW)); - p.bump(); - - name(p); - if !p.eat(SEMI) { - if p.expect(L_CURLY) { - mod_contents(p, true); - p.expect(R_CURLY); - } - } -} diff --git a/src/parser/grammar/items/structs.rs b/src/parser/grammar/items/structs.rs deleted file mode 100644 index 7ced542a4..000000000 --- a/src/parser/grammar/items/structs.rs +++ /dev/null @@ -1,116 +0,0 @@ -use super::*; - -pub(super) fn struct_item(p: &mut Parser) { - assert!(p.at(STRUCT_KW)); - p.bump(); - - name(p); - type_params::type_param_list(p); - match p.current() { - WHERE_KW => { - type_params::where_clause(p); - match p.current() { - SEMI => { - p.bump(); - return; - } - L_CURLY => named_fields(p), - _ => { - //TODO: special case `(` error message - p.error("expected `;` or `{`"); - return; - } - } - } - SEMI => { - p.bump(); - return; - } - L_CURLY => named_fields(p), - L_PAREN => { - pos_fields(p); - p.expect(SEMI); - } - _ => { - p.error("expected `;`, `{`, or `(`"); - return; - } - } -} - -pub(super) fn enum_item(p: &mut Parser) { - assert!(p.at(ENUM_KW)); - p.bump(); - name(p); - type_params::type_param_list(p); - type_params::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) { - p.bump(); - match p.current() { - L_CURLY => named_fields(p), - L_PAREN => pos_fields(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); - } - } - p.expect(R_CURLY); - } -} - -fn named_fields(p: &mut Parser) { - assert!(p.at(L_CURLY)); - p.bump(); - while !p.at(R_CURLY) && !p.at(EOF) { - named_field(p); - if !p.at(R_CURLY) { - p.expect(COMMA); - } - } - p.expect(R_CURLY); - - fn named_field(p: &mut Parser) { - let field = p.start(); - visibility(p); - if p.at(IDENT) { - name(p); - p.expect(COLON); - types::type_(p); - field.complete(p, NAMED_FIELD); - } else { - field.abandon(p); - p.err_and_bump("expected field declaration"); - } - } -} - -fn pos_fields(p: &mut Parser) { - if !p.expect(L_PAREN) { - return; - } - while !p.at(R_PAREN) && !p.at(EOF) { - let pos_field = p.start(); - visibility(p); - types::type_(p); - pos_field.complete(p, POS_FIELD); - - if !p.at(R_PAREN) { - p.expect(COMMA); - } - } - p.expect(R_PAREN); -} diff --git a/src/parser/grammar/items/traits.rs b/src/parser/grammar/items/traits.rs deleted file mode 100644 index bda13e565..000000000 --- a/src/parser/grammar/items/traits.rs +++ /dev/null @@ -1,77 +0,0 @@ -use super::*; - -// test trait_item -// trait T: Hash + Clone where U: Copy {} -pub(super) fn trait_item(p: &mut Parser) { - assert!(p.at(TRAIT_KW)); - p.bump(); - name(p); - type_params::type_param_list(p); - if p.at(COLON) { - type_params::bounds(p); - } - type_params::where_clause(p); - p.expect(L_CURLY); - p.expect(R_CURLY); -} - -// test impl_item -// impl Foo {} -pub(super) fn impl_item(p: &mut Parser) { - assert!(p.at(IMPL_KW)); - p.bump(); - if choose_type_params_over_qpath(p) { - type_params::type_param_list(p); - } - - // TODO: never type - // impl ! {} - - // test impl_item_neg - // impl !Send for X {} - p.eat(EXCL); - types::type_(p); - if p.eat(FOR_KW) { - types::type_(p); - } - type_params::where_clause(p); - p.expect(L_CURLY); - - // 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(p); - } - p.expect(R_CURLY); -} - -fn choose_type_params_over_qpath(p: &Parser) -> bool { - // There's an ambiguity between generic parameters and qualified paths in impls. - // If we see `<` it may start both, so we have to inspect some following tokens. - // The following combinations can only start generics, - // but not qualified paths (with one exception): - // `<` `>` - empty generic parameters - // `<` `#` - generic parameters with attributes - // `<` (LIFETIME|IDENT) `>` - single generic parameter - // `<` (LIFETIME|IDENT) `,` - first generic parameter in a list - // `<` (LIFETIME|IDENT) `:` - generic parameter with bounds - // `<` (LIFETIME|IDENT) `=` - generic parameter with a default - // The only truly ambiguous case is - // `<` IDENT `>` `::` IDENT ... - // we disambiguate it in favor of generics (`impl ::absolute::Path { ... }`) - // because this is what almost always expected in practice, qualified paths in impls - // (`impl ::AssocTy { ... }`) aren't even allowed by type checker at the moment. - if !p.at(L_ANGLE) { - return false; - } - if p.nth(1) == POUND || p.nth(1) == R_ANGLE { - return true; - } - (p.nth(1) == LIFETIME || p.nth(1) == IDENT) - && (p.nth(2) == R_ANGLE || p.nth(2) == COMMA || p.nth(2) == COLON || p.nth(2) == EQ) -} diff --git a/src/parser/grammar/items/use_item.rs b/src/parser/grammar/items/use_item.rs deleted file mode 100644 index a3f7f0da8..000000000 --- a/src/parser/grammar/items/use_item.rs +++ /dev/null @@ -1,66 +0,0 @@ -use super::*; - -pub(super) fn use_item(p: &mut Parser) { - assert!(p.at(USE_KW)); - p.bump(); - use_tree(p); - p.expect(SEMI); -} - -fn use_tree(p: &mut Parser) { - let la = p.nth(1); - let m = p.start(); - match (p.current(), la) { - (STAR, _) => p.bump(), - (COLONCOLON, STAR) => { - p.bump(); - p.bump(); - } - (L_CURLY, _) | (COLONCOLON, L_CURLY) => { - if p.at(COLONCOLON) { - p.bump(); - } - nested_trees(p); - } - _ if paths::is_path_start(p) => { - paths::use_path(p); - match p.current() { - AS_KW => { - alias(p); - } - COLONCOLON => { - p.bump(); - match p.current() { - STAR => { - p.bump(); - } - L_CURLY => nested_trees(p), - _ => { - // is this unreachable? - p.error("expected `{` or `*`"); - } - } - } - _ => (), - } - } - _ => { - m.abandon(p); - p.err_and_bump("expected one of `*`, `::`, `{`, `self`, `super`, `indent`"); - return; - } - } - m.complete(p, USE_TREE); -} - -fn nested_trees(p: &mut Parser) { - assert!(p.at(L_CURLY)); - p.bump(); - while !p.at(EOF) && !p.at(R_CURLY) { - use_tree(p); - if !p.at(R_CURLY) { - p.expect(COMMA); - } - } - p.expect(R_CURLY); -} diff --git a/src/parser/grammar/mod.rs b/src/parser/grammar/mod.rs deleted file mode 100644 index d4f9b80cf..000000000 --- a/src/parser/grammar/mod.rs +++ /dev/null @@ -1,144 +0,0 @@ -//! This is the actual "grammar" of the Rust language. -//! -//! Each function in this module and its children corresponds -//! to a production of the format grammar. Submodules roughly -//! correspond to different *areas* of the grammar. By convention, -//! each submodule starts with `use super::*` import and exports -//! "public" productions via `pub(super)`. -//! -//! See docs for `Parser` to learn about API, available to the grammar, -//! and see docs for `Event` to learn how this actually manages to -//! produce parse trees. -//! -//! Code in this module also contains inline tests, which start with -//! `// test name-of-the-test` comment and look like this: -//! -//! ``` -//! // test fn_item_with_zero_parameters -//! // fn foo() {} -//! ``` -//! -//! After adding a new inline-test, run `cargo collect-tests` to extract -//! it as a standalone text-fixture into `tests/data/parser/inline`, and -//! run `cargo test` once to create the "gold" value. -mod attributes; -mod expressions; -mod items; -mod paths; -mod patterns; -mod params; -mod type_params; -mod type_args; -mod types; - -use { - parser::{ - parser::{CompletedMarker, Parser}, - token_set::TokenSet, - }, - SyntaxKind::{self, *}, -}; - -pub(crate) fn file(p: &mut Parser) { - let file = p.start(); - p.eat(SHEBANG); - items::mod_contents(p, false); - file.complete(p, FILE); -} - -fn visibility(p: &mut Parser) { - if p.at(PUB_KW) { - let vis = p.start(); - p.bump(); - if p.at(L_PAREN) { - match p.nth(1) { - // test crate_visibility - // pub(crate) struct S; - // pub(self) struct S; - // pub(self) struct S; - // pub(self) struct S; - CRATE_KW | SELF_KW | SUPER_KW => { - p.bump(); - p.bump(); - p.expect(R_PAREN); - } - IN_KW => { - p.bump(); - p.bump(); - paths::use_path(p); - p.expect(R_PAREN); - } - _ => (), - } - } - vis.complete(p, VISIBILITY); - } -} - -fn alias(p: &mut Parser) -> bool { - if p.at(AS_KW) { - let alias = p.start(); - p.bump(); - name(p); - alias.complete(p, ALIAS); - } - true //FIXME: return false if three are errors -} - -fn abi(p: &mut Parser) { - assert!(p.at(EXTERN_KW)); - let abi = p.start(); - p.bump(); - match p.current() { - STRING | RAW_STRING => p.bump(), - _ => (), - } - abi.complete(p, ABI); -} - -fn fn_ret_type(p: &mut Parser) -> bool { - if p.at(THIN_ARROW) { - p.bump(); - types::type_(p); - true - } else { - false - } -} - -fn name(p: &mut Parser) { - if p.at(IDENT) { - let m = p.start(); - p.bump(); - m.complete(p, NAME); - } else { - p.error("expected a name"); - } -} - -fn name_ref(p: &mut Parser) { - if p.at(IDENT) { - let m = p.start(); - p.bump(); - m.complete(p, NAME_REF); - } else { - p.error("expected identifier"); - } -} - -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, - _ => (), - } - p.bump(); - } - err.complete(p, ERROR); -} diff --git a/src/parser/grammar/params.rs b/src/parser/grammar/params.rs deleted file mode 100644 index efa882394..000000000 --- a/src/parser/grammar/params.rs +++ /dev/null @@ -1,71 +0,0 @@ -use super::*; - -// test param_list -// fn a() {} -// fn b(x: i32) {} -// fn c(x: i32, ) {} -// fn d(x: i32, y: ()) {} -pub(super) fn param_list(p: &mut Parser) { - list_(p, true) -} - -pub(super) fn param_list_opt_types(p: &mut Parser) { - list_(p, false) -} - -fn list_(p: &mut Parser, require_types: bool) { - assert!(p.at(if require_types { L_PAREN } else { PIPE })); - let m = p.start(); - p.bump(); - if require_types { - self_param(p); - } - let terminator = if require_types { R_PAREN } else { PIPE }; - while !p.at(EOF) && !p.at(terminator) { - value_parameter(p, require_types); - if !p.at(terminator) { - p.expect(COMMA); - } - } - p.expect(terminator); - m.complete(p, PARAM_LIST); -} - -fn value_parameter(p: &mut Parser, require_type: bool) { - let m = p.start(); - patterns::pattern(p); - if p.at(COLON) || require_type { - types::ascription(p) - } - m.complete(p, PARAM); -} - -// test self_param -// impl S { -// fn a(self) {} -// fn b(&self,) {} -// fn c(&'a self,) {} -// fn d(&'a mut self, x: i32) {} -// } -fn self_param(p: &mut Parser) { - let la1 = p.nth(1); - let la2 = p.nth(2); - let la3 = p.nth(3); - let n_toks = match (p.current(), la1, la2, la3) { - (SELF_KW, _, _, _) => 1, - (AMPERSAND, SELF_KW, _, _) => 2, - (AMPERSAND, MUT_KW, SELF_KW, _) => 3, - (AMPERSAND, LIFETIME, SELF_KW, _) => 3, - (AMPERSAND, LIFETIME, MUT_KW, SELF_KW) => 4, - _ => return, - }; - let m = p.start(); - for _ in 0..n_toks { - p.bump(); - } - m.complete(p, SELF_PARAM); - if !p.at(R_PAREN) { - p.expect(COMMA); - } -} - diff --git a/src/parser/grammar/paths.rs b/src/parser/grammar/paths.rs deleted file mode 100644 index fe69db096..000000000 --- a/src/parser/grammar/paths.rs +++ /dev/null @@ -1,77 +0,0 @@ -use super::*; - -pub(super) fn is_path_start(p: &Parser) -> bool { - match p.current() { - IDENT | SELF_KW | SUPER_KW | COLONCOLON => true, - _ => false, - } -} - -pub(super) fn use_path(p: &mut Parser) { - path(p, Mode::Use) -} - -pub(super) fn type_path(p: &mut Parser) { - path(p, Mode::Type) -} - -pub(super) fn expr_path(p: &mut Parser) { - path(p, Mode::Expr) -} - -#[derive(Clone, Copy, Eq, PartialEq)] -enum Mode { - Use, - Type, - Expr, -} - -fn path(p: &mut Parser, mode: Mode) { - if !is_path_start(p) { - return; - } - let path = p.start(); - path_segment(p, mode, true); - let mut qual = path.complete(p, PATH); - loop { - let use_tree = match p.nth(1) { - STAR | L_CURLY => true, - _ => false, - }; - if p.at(COLONCOLON) && !use_tree { - let path = qual.precede(p); - p.bump(); - path_segment(p, mode, false); - let path = path.complete(p, PATH); - qual = path; - } else { - break; - } - } -} - -fn path_segment(p: &mut Parser, mode: Mode, first: bool) { - let segment = p.start(); - if first { - p.eat(COLONCOLON); - } - match p.current() { - IDENT => { - name_ref(p); - path_generic_args(p, mode); - } - SELF_KW | SUPER_KW => p.bump(), - _ => { - p.error("expected identifier"); - } - }; - segment.complete(p, PATH_SEGMENT); -} - -fn path_generic_args(p: &mut Parser, mode: Mode) { - match mode { - Mode::Use => return, - Mode::Type => type_args::type_arg_list(p, false), - Mode::Expr => type_args::type_arg_list(p, true), - } -} diff --git a/src/parser/grammar/patterns.rs b/src/parser/grammar/patterns.rs deleted file mode 100644 index 7216807fd..000000000 --- a/src/parser/grammar/patterns.rs +++ /dev/null @@ -1,53 +0,0 @@ -use super::*; - -pub(super) fn pattern(p: &mut Parser) { - match p.current() { - UNDERSCORE => placeholder_pat(p), - AMPERSAND => ref_pat(p), - IDENT | REF_KW | MUT_KW => bind_pat(p), - _ => p.err_and_bump("expected pattern"), - } -} - -// test placeholder_pat -// fn main() { let _ = (); } -fn placeholder_pat(p: &mut Parser) { - assert!(p.at(UNDERSCORE)); - let m = p.start(); - p.bump(); - m.complete(p, PLACEHOLDER_PAT); -} - -// test ref_pat -// fn main() { -// let &a = (); -// let &mut b = (); -// } -fn ref_pat(p: &mut Parser) { - assert!(p.at(AMPERSAND)); - let m = p.start(); - p.bump(); - p.eat(MUT_KW); - pattern(p); - m.complete(p, REF_PAT); -} - -// test bind_pat -// fn main() { -// let a = (); -// let mut b = (); -// let ref c = (); -// let ref mut d = (); -// let e @ _ = (); -// let ref mut f @ g @ _ = (); -// } -fn bind_pat(p: &mut Parser) { - let m = p.start(); - p.eat(REF_KW); - p.eat(MUT_KW); - name(p); - if p.eat(AT) { - pattern(p); - } - m.complete(p, BIND_PAT); -} diff --git a/src/parser/grammar/type_args.rs b/src/parser/grammar/type_args.rs deleted file mode 100644 index 5b960f10b..000000000 --- a/src/parser/grammar/type_args.rs +++ /dev/null @@ -1,48 +0,0 @@ -use super::*; - -pub(super) fn type_arg_list(p: &mut Parser, colon_colon_required: bool) { - let m; - match (colon_colon_required, p.nth(0), p.nth(1)) { - (_, COLONCOLON, L_ANGLE) => { - m = p.start(); - p.bump(); - p.bump(); - } - (false, L_ANGLE, _) => { - m = p.start(); - p.bump(); - } - _ => return, - }; - - while !p.at(EOF) && !p.at(R_ANGLE) { - type_arg(p); - if !p.at(R_ANGLE) && !p.expect(COMMA) { - break; - } - } - p.expect(R_ANGLE); - m.complete(p, TYPE_ARG_LIST); -} - -// test type_arg -// type A = B<'static, i32, Item=u64> -fn type_arg(p: &mut Parser) { - let m = p.start(); - match p.current() { - LIFETIME => { - p.bump(); - m.complete(p, LIFETIME_ARG); - } - IDENT if p.nth(1) == EQ => { - name_ref(p); - p.bump(); - types::type_(p); - m.complete(p, ASSOC_TYPE_ARG); - } - _ => { - types::type_(p); - m.complete(p, TYPE_ARG); - } - } -} diff --git a/src/parser/grammar/type_params.rs b/src/parser/grammar/type_params.rs deleted file mode 100644 index b31bf52b6..000000000 --- a/src/parser/grammar/type_params.rs +++ /dev/null @@ -1,96 +0,0 @@ -use super::*; - -pub(super) fn type_param_list(p: &mut Parser) { - if !p.at(L_ANGLE) { - return; - } - let m = p.start(); - p.bump(); - - while !p.at(EOF) && !p.at(R_ANGLE) { - match p.current() { - LIFETIME => lifetime_param(p), - IDENT => type_param(p), - _ => p.err_and_bump("expected type parameter"), - } - if !p.at(R_ANGLE) && !p.expect(COMMA) { - break; - } - } - p.expect(R_ANGLE); - m.complete(p, TYPE_PARAM_LIST); - - fn lifetime_param(p: &mut Parser) { - assert!(p.at(LIFETIME)); - let m = p.start(); - p.bump(); - if p.eat(COLON) { - while p.at(LIFETIME) { - p.bump(); - if !p.eat(PLUS) { - break; - } - } - } - m.complete(p, LIFETIME_PARAM); - } - - fn type_param(p: &mut Parser) { - assert!(p.at(IDENT)); - let m = p.start(); - name(p); - if p.at(COLON) { - bounds(p); - } - // test type_param_default - // struct S; - if p.at(EQ) { - p.bump(); - types::type_(p) - } - m.complete(p, TYPE_PARAM); - } -} - -// test type_param_bounds -// struct S; -pub(super) fn bounds(p: &mut Parser) { - assert!(p.at(COLON)); - p.bump(); - bounds_without_colon(p); -} - -pub(super) fn bounds_without_colon(p: &mut Parser) { - 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; - } - } -} - - -pub(super) fn where_clause(p: &mut Parser) { - if p.at(WHERE_KW) { - let m = p.start(); - p.bump(); - p.expect(IDENT); - p.expect(COLON); - p.expect(IDENT); - m.complete(p, WHERE_CLAUSE); - } -} diff --git a/src/parser/grammar/types.rs b/src/parser/grammar/types.rs deleted file mode 100644 index 565037cb0..000000000 --- a/src/parser/grammar/types.rs +++ /dev/null @@ -1,207 +0,0 @@ -use super::*; - -pub(super) fn type_(p: &mut Parser) { - match p.current() { - L_PAREN => paren_or_tuple_type(p), - EXCL => never_type(p), - STAR => pointer_type(p), - L_BRACK => array_or_slice_type(p), - AMPERSAND => reference_type(p), - UNDERSCORE => placeholder_type(p), - FN_KW | UNSAFE_KW | EXTERN_KW => fn_pointer_type(p), - FOR_KW => for_type(p), - IMPL_KW => impl_trait_type(p), - _ if paths::is_path_start(p) => path_type(p), - _ => { - p.error("expected type"); - } - } -} - -pub(super) fn ascription(p: &mut Parser) { - p.expect(COLON); - type_(p) -} - -fn type_no_plus(p: &mut Parser) { - type_(p); -} - -fn paren_or_tuple_type(p: &mut Parser) { - assert!(p.at(L_PAREN)); - let m = p.start(); - p.bump(); - let mut n_types: u32 = 0; - let mut trailing_comma: bool = false; - while !p.at(EOF) && !p.at(R_PAREN) { - n_types += 1; - type_(p); - if p.eat(COMMA) { - trailing_comma = true; - } else { - trailing_comma = false; - break; - } - } - p.expect(R_PAREN); - - let kind = if n_types == 1 && !trailing_comma { - // test paren_type - // type T = (i32); - PAREN_TYPE - } else { - // test unit_type - // type T = (); - - // test singleton_tuple_type - // type T = (i32,); - TUPLE_TYPE - }; - m.complete(p, kind); -} - -// test never_type -// type Never = !; -fn never_type(p: &mut Parser) { - assert!(p.at(EXCL)); - let m = p.start(); - p.bump(); - m.complete(p, NEVER_TYPE); -} - -fn pointer_type(p: &mut Parser) { - assert!(p.at(STAR)); - let m = p.start(); - p.bump(); - - match p.current() { - // test pointer_type_mut - // type M = *mut (); - // type C = *mut (); - MUT_KW | CONST_KW => p.bump(), - _ => { - // test pointer_type_no_mutability - // type T = *(); - p.error( - "expected mut or const in raw pointer type \ - (use `*mut T` or `*const T` as appropriate)", - ); - } - }; - - type_no_plus(p); - m.complete(p, POINTER_TYPE); -} - -fn array_or_slice_type(p: &mut Parser) { - assert!(p.at(L_BRACK)); - let m = p.start(); - p.bump(); - - type_(p); - let kind = match p.current() { - // test slice_type - // type T = [()]; - R_BRACK => { - p.bump(); - SLICE_TYPE - } - - // test array_type - // type T = [(); 92]; - SEMI => { - p.bump(); - expressions::expr(p); - p.expect(R_BRACK); - ARRAY_TYPE - } - // test array_type_missing_semi - // type T = [() 92]; - _ => { - p.error("expected `;` or `]`"); - SLICE_TYPE - } - }; - m.complete(p, kind); -} - -// test reference_type; -// type A = &(); -// type B = &'static (); -// type C = &mut (); -fn reference_type(p: &mut Parser) { - assert!(p.at(AMPERSAND)); - let m = p.start(); - p.bump(); - p.eat(LIFETIME); - p.eat(MUT_KW); - type_no_plus(p); - m.complete(p, REFERENCE_TYPE); -} - -// test placeholder_type -// type Placeholder = _; -fn placeholder_type(p: &mut Parser) { - assert!(p.at(UNDERSCORE)); - let m = p.start(); - p.bump(); - m.complete(p, PLACEHOLDER_TYPE); -} - -// test fn_pointer_type -// type A = fn(); -// type B = unsafe fn(); -// type C = unsafe extern "C" fn(); -fn fn_pointer_type(p: &mut Parser) { - let m = p.start(); - p.eat(UNSAFE_KW); - if p.at(EXTERN_KW) { - abi(p); - } - // test fn_pointer_type_missing_fn - // type F = unsafe (); - if !p.eat(FN_KW) { - m.abandon(p); - p.error("expected `fn`"); - return; - } - - params::param_list(p); - // test fn_pointer_type_with_ret - // type F = fn() -> (); - fn_ret_type(p); - m.complete(p, FN_POINTER_TYPE); -} - -// test for_type -// type A = for<'a> fn() -> (); -fn for_type(p: &mut Parser) { - assert!(p.at(FOR_KW)); - let m = p.start(); - p.bump(); - type_params::type_param_list(p); - type_(p); - m.complete(p, FOR_TYPE); -} - -// test impl_trait_type -// type A = impl Iterator> + 'a; -fn impl_trait_type(p: &mut Parser) { - assert!(p.at(IMPL_KW)); - let m = p.start(); - p.bump(); - type_params::bounds_without_colon(p); - m.complete(p, IMPL_TRAIT_TYPE); -} - -// test path_type -// type A = Foo; -// type B = ::Foo; -// type C = self::Foo; -// type D = super::Foo; -fn path_type(p: &mut Parser) { - assert!(paths::is_path_start(p)); - let m = p.start(); - paths::type_path(p); - m.complete(p, PATH_TYPE); -} -- cgit v1.2.3