From 9f87c9a3f927d3b7a3cbb92818c45c979ece693b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 31 Jul 2018 17:35:54 +0300 Subject: Field expr --- src/grammar.ron | 2 + src/parser/grammar/expressions.rs | 43 +++++++++++++++++-- src/syntax_kinds/generated.rs | 4 ++ tests/data/parser/inline/0051_method_call_expr.rs | 4 ++ tests/data/parser/inline/0051_method_call_expr.txt | 50 ++++++++++++++++++++++ tests/data/parser/inline/0052_field_expr.rs | 3 ++ tests/data/parser/inline/0052_field_expr.txt | 29 +++++++++++++ tools/src/lib.rs | 1 - 8 files changed, 131 insertions(+), 5 deletions(-) create mode 100644 tests/data/parser/inline/0051_method_call_expr.rs create mode 100644 tests/data/parser/inline/0051_method_call_expr.txt create mode 100644 tests/data/parser/inline/0052_field_expr.rs create mode 100644 tests/data/parser/inline/0052_field_expr.txt diff --git a/src/grammar.ron b/src/grammar.ron index a8c922040..fca29f1ef 100644 --- a/src/grammar.ron +++ b/src/grammar.ron @@ -126,6 +126,8 @@ Grammar( "TUPLE_EXPR", "PATH_EXPR", "CALL_EXPR", + "METHOD_CALL_EXPR", + "FIELD_EXPR", "REF_EXPR", "EXTERN_BLOCK", diff --git a/src/parser/grammar/expressions.rs b/src/parser/grammar/expressions.rs index 11bb3436b..3956df568 100644 --- a/src/parser/grammar/expressions.rs +++ b/src/parser/grammar/expressions.rs @@ -26,11 +26,20 @@ pub(super) fn literal(p: &mut Parser) -> Option { } pub(super) fn expr(p: &mut Parser) { - let mut lhs = prefix_expr(p); + let mut lhs = match prefix_expr(p) { + Some(lhs) => lhs, + None => return, + }; - while let Some(m) = lhs { - match p.current() { - L_PAREN => lhs = Some(call_expr(p, m)), + 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, } } @@ -95,6 +104,32 @@ fn call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { 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(); diff --git a/src/syntax_kinds/generated.rs b/src/syntax_kinds/generated.rs index c49ad9a59..699f5282e 100644 --- a/src/syntax_kinds/generated.rs +++ b/src/syntax_kinds/generated.rs @@ -117,6 +117,8 @@ pub enum SyntaxKind { TUPLE_EXPR, PATH_EXPR, CALL_EXPR, + METHOD_CALL_EXPR, + FIELD_EXPR, REF_EXPR, EXTERN_BLOCK, ENUM_VARIANT, @@ -268,6 +270,8 @@ impl SyntaxKind { TUPLE_EXPR => &SyntaxInfo { name: "TUPLE_EXPR" }, PATH_EXPR => &SyntaxInfo { name: "PATH_EXPR" }, CALL_EXPR => &SyntaxInfo { name: "CALL_EXPR" }, + METHOD_CALL_EXPR => &SyntaxInfo { name: "METHOD_CALL_EXPR" }, + FIELD_EXPR => &SyntaxInfo { name: "FIELD_EXPR" }, REF_EXPR => &SyntaxInfo { name: "REF_EXPR" }, EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" }, ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" }, diff --git a/tests/data/parser/inline/0051_method_call_expr.rs b/tests/data/parser/inline/0051_method_call_expr.rs new file mode 100644 index 000000000..236d94e88 --- /dev/null +++ b/tests/data/parser/inline/0051_method_call_expr.rs @@ -0,0 +1,4 @@ +fn foo() { + x.foo(); + y.bar(1, 2,); +} diff --git a/tests/data/parser/inline/0051_method_call_expr.txt b/tests/data/parser/inline/0051_method_call_expr.txt new file mode 100644 index 000000000..69e13bd2a --- /dev/null +++ b/tests/data/parser/inline/0051_method_call_expr.txt @@ -0,0 +1,50 @@ +FILE@[0; 44) + FN_ITEM@[0; 44) + FN_KW@[0; 2) + NAME@[2; 6) + WHITESPACE@[2; 3) + IDENT@[3; 6) "foo" + PARAM_LIST@[6; 9) + L_PAREN@[6; 7) + R_PAREN@[7; 8) + WHITESPACE@[8; 9) + BLOCK@[9; 44) + L_CURLY@[9; 10) + EXPR_STMT@[10; 28) + METHOD_CALL_EXPR@[10; 22) + PATH_EXPR@[10; 16) + PATH@[10; 16) + PATH_SEGMENT@[10; 16) + NAME_REF@[10; 16) + WHITESPACE@[10; 15) + IDENT@[15; 16) "x" + DOT@[16; 17) + IDENT@[17; 20) "foo" + ARG_LIST@[20; 22) + L_PAREN@[20; 21) + R_PAREN@[21; 22) + SEMI@[22; 23) + WHITESPACE@[23; 28) + EXPR_STMT@[28; 42) + METHOD_CALL_EXPR@[28; 40) + PATH_EXPR@[28; 29) + PATH@[28; 29) + PATH_SEGMENT@[28; 29) + NAME_REF@[28; 29) + IDENT@[28; 29) "y" + DOT@[29; 30) + IDENT@[30; 33) "bar" + ARG_LIST@[33; 40) + L_PAREN@[33; 34) + LITERAL@[34; 35) + INT_NUMBER@[34; 35) + COMMA@[35; 36) + LITERAL@[36; 38) + WHITESPACE@[36; 37) + INT_NUMBER@[37; 38) + COMMA@[38; 39) + R_PAREN@[39; 40) + SEMI@[40; 41) + WHITESPACE@[41; 42) + R_CURLY@[42; 43) + WHITESPACE@[43; 44) diff --git a/tests/data/parser/inline/0052_field_expr.rs b/tests/data/parser/inline/0052_field_expr.rs new file mode 100644 index 000000000..874887eae --- /dev/null +++ b/tests/data/parser/inline/0052_field_expr.rs @@ -0,0 +1,3 @@ +fn foo() { + x.foo.bar; +} diff --git a/tests/data/parser/inline/0052_field_expr.txt b/tests/data/parser/inline/0052_field_expr.txt new file mode 100644 index 000000000..0ef2c5836 --- /dev/null +++ b/tests/data/parser/inline/0052_field_expr.txt @@ -0,0 +1,29 @@ +FILE@[0; 28) + FN_ITEM@[0; 28) + FN_KW@[0; 2) + NAME@[2; 6) + WHITESPACE@[2; 3) + IDENT@[3; 6) "foo" + PARAM_LIST@[6; 9) + L_PAREN@[6; 7) + R_PAREN@[7; 8) + WHITESPACE@[8; 9) + BLOCK@[9; 28) + L_CURLY@[9; 10) + EXPR_STMT@[10; 26) + FIELD_EXPR@[10; 24) + FIELD_EXPR@[10; 20) + PATH_EXPR@[10; 16) + PATH@[10; 16) + PATH_SEGMENT@[10; 16) + NAME_REF@[10; 16) + WHITESPACE@[10; 15) + IDENT@[15; 16) "x" + DOT@[16; 17) + IDENT@[17; 20) "foo" + DOT@[20; 21) + IDENT@[21; 24) "bar" + SEMI@[24; 25) + WHITESPACE@[25; 26) + R_CURLY@[26; 27) + WHITESPACE@[27; 28) diff --git a/tools/src/lib.rs b/tools/src/lib.rs index 5a7d846ff..97a56a31f 100644 --- a/tools/src/lib.rs +++ b/tools/src/lib.rs @@ -1,7 +1,6 @@ extern crate itertools; use itertools::Itertools; -use std::hash; #[derive(Debug)] pub struct Test { -- cgit v1.2.3