Field expr

This commit is contained in:
Aleksey Kladov 2018-07-31 17:35:54 +03:00
parent 9ce7e81102
commit 9f87c9a3f9
8 changed files with 131 additions and 5 deletions

View file

@ -126,6 +126,8 @@ Grammar(
"TUPLE_EXPR",
"PATH_EXPR",
"CALL_EXPR",
"METHOD_CALL_EXPR",
"FIELD_EXPR",
"REF_EXPR",
"EXTERN_BLOCK",

View file

@ -26,11 +26,20 @@ pub(super) fn literal(p: &mut Parser) -> Option<CompletedMarker> {
}
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();

View file

@ -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" },

View file

@ -0,0 +1,4 @@
fn foo() {
x.foo();
y.bar(1, 2,);
}

View file

@ -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)

View file

@ -0,0 +1,3 @@
fn foo() {
x.foo.bar;
}

View file

@ -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)

View file

@ -1,7 +1,6 @@
extern crate itertools;
use itertools::Itertools;
use std::hash;
#[derive(Debug)]
pub struct Test {