From 08f7c69f90bac772c69b3bf34877f3d9a845c541 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 13 Jan 2018 22:00:26 +0300 Subject: G: struct flavors --- src/parser/event_parser/grammar/items.rs | 86 +++++++++++++++++++++++++++++--- src/parser/event_parser/grammar/mod.rs | 16 ++++-- src/parser/event_parser/grammar/types.rs | 5 ++ 3 files changed, 97 insertions(+), 10 deletions(-) create mode 100644 src/parser/event_parser/grammar/types.rs (limited to 'src/parser/event_parser/grammar') diff --git a/src/parser/event_parser/grammar/items.rs b/src/parser/event_parser/grammar/items.rs index 2f64111ab..a14f6de77 100644 --- a/src/parser/event_parser/grammar/items.rs +++ b/src/parser/event_parser/grammar/items.rs @@ -56,8 +56,84 @@ fn item(p: &mut Parser) -> bool { } fn struct_item(p: &mut Parser) { - p.expect(IDENT) - && p.curly_block(|p| comma_list(p, EOF, struct_field)); + if !p.expect(IDENT) { + return + } + generic_parameters(p); + match p.current() { + WHERE_KW => { + where_clause(p); + match p.current() { + SEMI => { + p.bump(); + return + } + L_CURLY => named_fields(p), + _ => { //TODO: special case `(` error message + p.error() + .message("expected `;` or `{`") + .emit(); + return + } + } + } + SEMI => { + p.bump(); + return + } + L_CURLY => named_fields(p), + L_PAREN => { + tuple_fields(p); + p.expect(SEMI); + }, + _ => { + p.error() + .message("expected `;`, `{`, or `(`") + .emit(); + return + } + } +} + +fn named_fields(p: &mut Parser) { + p.curly_block(|p| comma_list(p, EOF, |p| { + named_field(p); + true + })); + + fn named_field(p: &mut Parser) { + node(p, NAMED_FIELD, |p| { + visibility(p); + p.expect(IDENT) && p.expect(COLON) && { + types::type_ref(p); + true + }; + }) + } +} + +fn tuple_fields(p: &mut Parser) { + if !p.expect(L_PAREN) { + return + } + comma_list(p, R_PAREN, |p| { + tuple_field(p); + true + }); + p.expect(R_PAREN); + + fn tuple_field(p: &mut Parser) { + node(p, POS_FIELD, |p| { + visibility(p); + types::type_ref(p); + }) + } +} + +fn generic_parameters(_: &mut Parser) { +} + +fn where_clause(_: &mut Parser) { } fn extern_crate_item(p: &mut Parser) { @@ -133,11 +209,7 @@ fn use_item(p: &mut Parser) { } } -fn struct_field(p: &mut Parser) -> bool { - node_if(p, IDENT, STRUCT_FIELD, |p| { - p.expect(COLON) && p.expect(IDENT); - }) -} + fn fn_item(p: &mut Parser) { p.expect(IDENT) && p.expect(L_PAREN) && p.expect(R_PAREN) diff --git a/src/parser/event_parser/grammar/mod.rs b/src/parser/event_parser/grammar/mod.rs index 1c57e0cb4..881bb3ef3 100644 --- a/src/parser/event_parser/grammar/mod.rs +++ b/src/parser/event_parser/grammar/mod.rs @@ -6,6 +6,7 @@ use syntax_kinds::*; mod items; mod attributes; mod expressions; +mod types; mod paths; pub(crate) fn file(p: &mut Parser) { @@ -72,12 +73,21 @@ fn many bool>(p: &mut Parser, mut f: F) { fn comma_list bool>(p: &mut Parser, end: SyntaxKind, f: F) { many(p, |p| { - if !f(p) || p.current() == end { - false + if p.current() == end { + return false + } + let pos = p.pos(); + f(p); + if p.pos() == pos { + return false + } + + if p.current() == end { + p.eat(COMMA); } else { p.expect(COMMA); - true } + true }) } diff --git a/src/parser/event_parser/grammar/types.rs b/src/parser/event_parser/grammar/types.rs new file mode 100644 index 000000000..c431643d7 --- /dev/null +++ b/src/parser/event_parser/grammar/types.rs @@ -0,0 +1,5 @@ +use super::*; + +pub(super) fn type_ref(p: &mut Parser) { + p.expect(IDENT); +} \ No newline at end of file -- cgit v1.2.3