no-struct-literal-restr

This commit is contained in:
Aleksey Kladov 2018-08-04 17:12:00 +03:00
parent c548382252
commit 82efdff34b
6 changed files with 137 additions and 100 deletions

View File

@ -33,13 +33,13 @@ pub(crate) fn literal(p: &mut Parser) -> Option<CompletedMarker> {
IDENT, SELF_KW, SUPER_KW, COLONCOLON ],
];
pub(super) fn atom_expr(p: &mut Parser) -> Option<CompletedMarker> {
pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<CompletedMarker> {
match literal(p) {
Some(m) => return Some(m),
None => (),
}
if paths::is_path_start(p) {
return Some(path_expr(p));
return Some(path_expr(p, r));
}
let la = p.nth(1);
let done = match p.current() {
@ -91,7 +91,8 @@ fn lambda_expr(p: &mut Parser) -> CompletedMarker {
// fn foo() {
// if true {};
// if true {} else {};
// if true {} else if false {} else {}
// if true {} else if false {} else {};
// if S {};
// }
fn if_expr(p: &mut Parser) -> CompletedMarker {
assert!(p.at(IF_KW));
@ -112,18 +113,19 @@ fn if_expr(p: &mut Parser) -> CompletedMarker {
fn if_head(p: &mut Parser) {
assert!(p.at(IF_KW));
p.bump();
expr(p);
expr_no_struct(p);
}
// test match_expr
// fn foo() {
// match () { };
// match S {};
// }
fn match_expr(p: &mut Parser) -> CompletedMarker {
assert!(p.at(MATCH_KW));
let m = p.start();
p.bump();
expr(p);
expr_no_struct(p);
p.eat(L_CURLY);
while !p.at(EOF) && !p.at(R_CURLY) {
match_arm(p);

View File

@ -6,7 +6,13 @@
const EXPR_FIRST: TokenSet = UNARY_EXPR_FIRST;
pub(super) fn expr(p: &mut Parser) {
expr_bp(p, 1)
let r = Restrictions { forbid_structs: false };
expr_bp(p, r, 1)
}
fn expr_no_struct(p: &mut Parser) {
let r = Restrictions { forbid_structs: true };
expr_bp(p, r, 1)
}
// test block
@ -22,6 +28,11 @@ pub(super) fn block(p: &mut Parser) {
atom::block_expr(p);
}
#[derive(Clone, Copy)]
struct Restrictions {
forbid_structs: bool
}
// test expr_binding_power
// fn foo() {
// 1 + 2 * 3 == 1 * 2 + 3
@ -36,8 +47,8 @@ fn bp_of(op: SyntaxKind) -> u8 {
}
// Parses expression with binding power of at least bp.
fn expr_bp(p: &mut Parser, bp: u8) {
let mut lhs = match unary_expr(p) {
fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) {
let mut lhs = match unary_expr(p, r) {
Some(lhs) => lhs,
None => return,
};
@ -47,7 +58,7 @@ fn expr_bp(p: &mut Parser, bp: u8) {
if op_bp < bp {
break;
}
lhs = bin_expr(p, lhs, op_bp);
lhs = bin_expr(p, r, lhs, op_bp);
}
}
@ -57,17 +68,46 @@ fn expr_bp(p: &mut Parser, bp: u8) {
atom::ATOM_EXPR_FIRST,
];
fn unary_expr(p: &mut Parser) -> Option<CompletedMarker> {
let done = match p.current() {
AMPERSAND => ref_expr(p),
STAR => deref_expr(p),
EXCL => not_expr(p),
fn unary_expr(p: &mut Parser, r: Restrictions) -> Option<CompletedMarker> {
let m;
let kind = match p.current() {
// test ref_expr
// fn foo() {
// let _ = &1;
// let _ = &mut &f();
// }
AMPERSAND => {
m = p.start();
p.bump();
p.eat(MUT_KW);
REF_EXPR
},
// test deref_expr
// fn foo() {
// **&1;
// }
STAR => {
m = p.start();
p.bump();
DEREF_EXPR
},
// test not_expr
// fn foo() {
// !!true;
// }
EXCL => {
m = p.start();
p.bump();
NOT_EXPR
},
_ => {
let lhs = atom::atom_expr(p)?;
postfix_expr(p, lhs)
let lhs = atom::atom_expr(p, r)?;
return Some(postfix_expr(p, lhs))
}
};
Some(done)
expr(p);
Some(m.complete(p, kind))
}
fn postfix_expr(p: &mut Parser, mut lhs: CompletedMarker) -> CompletedMarker {
@ -87,44 +127,6 @@ fn postfix_expr(p: &mut Parser, mut lhs: CompletedMarker) -> CompletedMarker {
lhs
}
// 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)
}
// test not_expr
// fn foo() {
// !!true;
// }
fn not_expr(p: &mut Parser) -> CompletedMarker {
assert!(p.at(EXCL));
let m = p.start();
p.bump();
expr(p);
m.complete(p, NOT_EXPR)
}
// test call_expr
// fn foo() {
// let _ = f();
@ -199,11 +201,11 @@ fn arg_list(p: &mut Parser) {
// let _ = a::b;
// let _ = ::a::<b>;
// }
fn path_expr(p: &mut Parser) -> CompletedMarker {
fn path_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker {
assert!(paths::is_path_start(p));
let m = p.start();
paths::expr_path(p);
if p.at(L_CURLY) {
if p.at(L_CURLY) && !r.forbid_structs {
struct_lit(p);
m.complete(p, STRUCT_LIT)
} else {
@ -243,13 +245,13 @@ fn struct_lit(p: &mut Parser) {
p.expect(R_CURLY);
}
fn bin_expr(p: &mut Parser, lhs: CompletedMarker, bp: u8) -> CompletedMarker {
fn bin_expr(p: &mut Parser, r: Restrictions, lhs: CompletedMarker, bp: u8) -> CompletedMarker {
assert!(match p.current() {
MINUS | PLUS | STAR | SLASH | EQEQ | NEQ => true,
_ => false,
});
let m = lhs.precede(p);
p.bump();
expr_bp(p, bp);
expr_bp(p, r, bp);
m.complete(p, BIN_EXPR)
}

View File

@ -1,5 +1,6 @@
fn foo() {
if true {};
if true {} else {};
if true {} else if false {} else {}
if true {} else if false {} else {};
if S {};
}

View File

@ -1,5 +1,5 @@
FILE@[0; 93)
FN_ITEM@[0; 93)
FILE@[0; 107)
FN_ITEM@[0; 107)
FN_KW@[0; 2)
NAME@[2; 6)
WHITESPACE@[2; 3)
@ -8,7 +8,7 @@ FILE@[0; 93)
L_PAREN@[6; 7)
R_PAREN@[7; 8)
WHITESPACE@[8; 9)
BLOCK_EXPR@[9; 93)
BLOCK_EXPR@[9; 107)
L_CURLY@[9; 10)
EXPR_STMT@[10; 31)
IF_EXPR@[10; 25)
@ -41,33 +41,50 @@ FILE@[0; 93)
R_CURLY@[48; 49)
SEMI@[49; 50)
WHITESPACE@[50; 55)
IF_EXPR@[55; 91)
IF_KW@[55; 57)
LITERAL@[57; 63)
WHITESPACE@[57; 58)
TRUE_KW@[58; 62)
WHITESPACE@[62; 63)
BLOCK_EXPR@[63; 66)
L_CURLY@[63; 64)
R_CURLY@[64; 65)
WHITESPACE@[65; 66)
ELSE_KW@[66; 70)
IF_EXPR@[70; 91)
WHITESPACE@[70; 71)
IF_KW@[71; 73)
LITERAL@[73; 80)
WHITESPACE@[73; 74)
FALSE_KW@[74; 79)
WHITESPACE@[79; 80)
BLOCK_EXPR@[80; 83)
L_CURLY@[80; 81)
R_CURLY@[81; 82)
WHITESPACE@[82; 83)
ELSE_KW@[83; 87)
BLOCK_EXPR@[87; 91)
WHITESPACE@[87; 88)
L_CURLY@[88; 89)
R_CURLY@[89; 90)
WHITESPACE@[90; 91)
R_CURLY@[91; 92)
WHITESPACE@[92; 93)
EXPR_STMT@[55; 96)
IF_EXPR@[55; 90)
IF_KW@[55; 57)
LITERAL@[57; 63)
WHITESPACE@[57; 58)
TRUE_KW@[58; 62)
WHITESPACE@[62; 63)
BLOCK_EXPR@[63; 66)
L_CURLY@[63; 64)
R_CURLY@[64; 65)
WHITESPACE@[65; 66)
ELSE_KW@[66; 70)
IF_EXPR@[70; 90)
WHITESPACE@[70; 71)
IF_KW@[71; 73)
LITERAL@[73; 80)
WHITESPACE@[73; 74)
FALSE_KW@[74; 79)
WHITESPACE@[79; 80)
BLOCK_EXPR@[80; 83)
L_CURLY@[80; 81)
R_CURLY@[81; 82)
WHITESPACE@[82; 83)
ELSE_KW@[83; 87)
BLOCK_EXPR@[87; 90)
WHITESPACE@[87; 88)
L_CURLY@[88; 89)
R_CURLY@[89; 90)
SEMI@[90; 91)
WHITESPACE@[91; 96)
EXPR_STMT@[96; 105)
IF_EXPR@[96; 103)
IF_KW@[96; 98)
PATH_EXPR@[98; 101)
PATH@[98; 101)
PATH_SEGMENT@[98; 101)
NAME_REF@[98; 101)
WHITESPACE@[98; 99)
IDENT@[99; 100) "S"
WHITESPACE@[100; 101)
BLOCK_EXPR@[101; 103)
L_CURLY@[101; 102)
R_CURLY@[102; 103)
SEMI@[103; 104)
WHITESPACE@[104; 105)
R_CURLY@[105; 106)
WHITESPACE@[106; 107)

View File

@ -1,3 +1,4 @@
fn foo() {
match () { };
match S {};
}

View File

@ -1,5 +1,5 @@
FILE@[0; 31)
FN_ITEM@[0; 31)
FILE@[0; 47)
FN_ITEM@[0; 47)
FN_KW@[0; 2)
NAME@[2; 6)
WHITESPACE@[2; 3)
@ -8,9 +8,9 @@ FILE@[0; 31)
L_PAREN@[6; 7)
R_PAREN@[7; 8)
WHITESPACE@[8; 9)
BLOCK_EXPR@[9; 31)
BLOCK_EXPR@[9; 47)
L_CURLY@[9; 10)
EXPR_STMT@[10; 29)
EXPR_STMT@[10; 33)
MATCH_EXPR@[10; 27)
WHITESPACE@[10; 15)
MATCH_KW@[15; 20)
@ -23,6 +23,20 @@ FILE@[0; 31)
WHITESPACE@[25; 26)
R_CURLY@[26; 27)
SEMI@[27; 28)
WHITESPACE@[28; 29)
R_CURLY@[29; 30)
WHITESPACE@[30; 31)
WHITESPACE@[28; 33)
EXPR_STMT@[33; 45)
MATCH_EXPR@[33; 43)
MATCH_KW@[33; 38)
PATH_EXPR@[38; 41)
PATH@[38; 41)
PATH_SEGMENT@[38; 41)
NAME_REF@[38; 41)
WHITESPACE@[38; 39)
IDENT@[39; 40) "S"
WHITESPACE@[40; 41)
L_CURLY@[41; 42)
R_CURLY@[42; 43)
SEMI@[43; 44)
WHITESPACE@[44; 45)
R_CURLY@[45; 46)
WHITESPACE@[46; 47)