Fix parsing of blocks without {

This commit is contained in:
Aleksey Kladov 2020-05-02 14:34:39 +02:00
parent fb8fb65131
commit 359d3be308
11 changed files with 107 additions and 62 deletions

View file

@ -54,7 +54,7 @@ pub(crate) mod fragments {
use super::*; use super::*;
pub(crate) use super::{ pub(crate) use super::{
expressions::block, paths::type_path as path, patterns::pattern, types::type_, expressions::block_expr, paths::type_path as path, patterns::pattern, types::type_,
}; };
pub(crate) fn expr(p: &mut Parser) { pub(crate) fn expr(p: &mut Parser) {
@ -143,7 +143,7 @@ pub(crate) fn reparser(
parent: Option<SyntaxKind>, parent: Option<SyntaxKind>,
) -> Option<fn(&mut Parser)> { ) -> Option<fn(&mut Parser)> {
let res = match node { let res = match node {
BLOCK_EXPR => expressions::block, BLOCK_EXPR => expressions::block_expr,
RECORD_FIELD_DEF_LIST => items::record_field_def_list, RECORD_FIELD_DEF_LIST => items::record_field_def_list,
RECORD_FIELD_LIST => items::record_field_list, RECORD_FIELD_LIST => items::record_field_list,
ENUM_VARIANT_LIST => items::enum_variant_list, ENUM_VARIANT_LIST => items::enum_variant_list,

View file

@ -2,7 +2,7 @@
mod atom; mod atom;
pub(crate) use self::atom::match_arm_list; pub(crate) use self::atom::{block_expr, match_arm_list};
pub(super) use self::atom::{literal, LITERAL_FIRST}; pub(super) use self::atom::{literal, LITERAL_FIRST};
use super::*; use super::*;
@ -49,19 +49,6 @@ fn expr_no_struct(p: &mut Parser) {
expr_bp(p, r, 1); expr_bp(p, r, 1);
} }
// test block
// fn a() {}
// fn b() { let _ = 1; }
// fn c() { 1; 2; }
// fn d() { 1; 2 }
pub(crate) fn block(p: &mut Parser) {
if !p.at(T!['{']) {
p.error("expected a block");
return;
}
atom::block_expr(p);
}
fn is_expr_stmt_attr_allowed(kind: SyntaxKind) -> bool { fn is_expr_stmt_attr_allowed(kind: SyntaxKind) -> bool {
match kind { match kind {
BIN_EXPR | RANGE_EXPR | IF_EXPR => false, BIN_EXPR | RANGE_EXPR | IF_EXPR => false,

View file

@ -132,7 +132,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
// break; // break;
// } // }
// } // }
block_expr(p) block_expr_unchecked(p)
} }
T![return] => return_expr(p), T![return] => return_expr(p),
T![continue] => continue_expr(p), T![continue] => continue_expr(p),
@ -240,13 +240,9 @@ fn lambda_expr(p: &mut Parser) -> CompletedMarker {
p.eat(T![move]); p.eat(T![move]);
params::param_list_closure(p); params::param_list_closure(p);
if opt_fn_ret_type(p) { if opt_fn_ret_type(p) {
if p.at(T!['{']) { // test lambda_ret_block
// test lambda_ret_block // fn main() { || -> i32 { 92 }(); }
// fn main() { || -> i32 { 92 }(); } block_expr(p);
block_expr(p);
} else {
p.error("expected `{`");
}
} else { } else {
if p.at_ts(EXPR_FIRST) { if p.at_ts(EXPR_FIRST) {
expr(p); expr(p);
@ -270,13 +266,13 @@ fn if_expr(p: &mut Parser) -> CompletedMarker {
let m = p.start(); let m = p.start();
p.bump(T![if]); p.bump(T![if]);
cond(p); cond(p);
block(p); block_expr(p);
if p.at(T![else]) { if p.at(T![else]) {
p.bump(T![else]); p.bump(T![else]);
if p.at(T![if]) { if p.at(T![if]) {
if_expr(p); if_expr(p);
} else { } else {
block(p); block_expr(p);
} }
} }
m.complete(p, IF_EXPR) m.complete(p, IF_EXPR)
@ -304,7 +300,7 @@ fn loop_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
assert!(p.at(T![loop])); assert!(p.at(T![loop]));
let m = m.unwrap_or_else(|| p.start()); let m = m.unwrap_or_else(|| p.start());
p.bump(T![loop]); p.bump(T![loop]);
block(p); block_expr(p);
m.complete(p, LOOP_EXPR) m.complete(p, LOOP_EXPR)
} }
@ -319,7 +315,7 @@ fn while_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
let m = m.unwrap_or_else(|| p.start()); let m = m.unwrap_or_else(|| p.start());
p.bump(T![while]); p.bump(T![while]);
cond(p); cond(p);
block(p); block_expr(p);
m.complete(p, WHILE_EXPR) m.complete(p, WHILE_EXPR)
} }
@ -334,7 +330,7 @@ fn for_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
patterns::pattern(p); patterns::pattern(p);
p.expect(T![in]); p.expect(T![in]);
expr_no_struct(p); expr_no_struct(p);
block(p); block_expr(p);
m.complete(p, FOR_EXPR) m.complete(p, FOR_EXPR)
} }
@ -467,11 +463,20 @@ fn match_guard(p: &mut Parser) -> CompletedMarker {
m.complete(p, MATCH_GUARD) m.complete(p, MATCH_GUARD)
} }
// test block_expr // test block
// fn foo() { // fn a() {}
// {}; // fn b() { let _ = 1; }
// } // fn c() { 1; 2; }
pub(super) fn block_expr(p: &mut Parser) -> CompletedMarker { // fn d() { 1; 2 }
pub(crate) fn block_expr(p: &mut Parser) {
if !p.at(T!['{']) {
p.error("expected a block");
return;
}
block_expr_unchecked(p);
}
fn block_expr_unchecked(p: &mut Parser) -> CompletedMarker {
assert!(p.at(T!['{'])); assert!(p.at(T!['{']));
let m = p.start(); let m = p.start();
p.bump(T!['{']); p.bump(T!['{']);

View file

@ -329,7 +329,7 @@ fn fn_def(p: &mut Parser) {
if p.at(T![;]) { if p.at(T![;]) {
p.bump(T![;]); p.bump(T![;]);
} else { } else {
expressions::block(p) expressions::block_expr(p)
} }
} }

View file

@ -48,7 +48,7 @@ fn type_arg(p: &mut Parser) {
m.complete(p, ASSOC_TYPE_ARG); m.complete(p, ASSOC_TYPE_ARG);
} }
T!['{'] => { T!['{'] => {
expressions::block(p); expressions::block_expr(p);
m.complete(p, CONST_ARG); m.complete(p, CONST_ARG);
} }
k if k.is_literal() => { k if k.is_literal() => {

View file

@ -112,7 +112,7 @@ pub fn parse_fragment(
FragmentKind::Type => grammar::fragments::type_, FragmentKind::Type => grammar::fragments::type_,
FragmentKind::Pattern => grammar::fragments::pattern, FragmentKind::Pattern => grammar::fragments::pattern,
FragmentKind::Item => grammar::fragments::item, FragmentKind::Item => grammar::fragments::item,
FragmentKind::Block => grammar::fragments::block, FragmentKind::Block => grammar::fragments::block_expr,
FragmentKind::Visibility => grammar::fragments::opt_visibility, FragmentKind::Visibility => grammar::fragments::opt_visibility,
FragmentKind::MetaItem => grammar::fragments::meta_item, FragmentKind::MetaItem => grammar::fragments::meta_item,
FragmentKind::Statement => grammar::fragments::stmt, FragmentKind::Statement => grammar::fragments::stmt,

View file

@ -40,5 +40,5 @@ SOURCE_FILE@0..42
WHITESPACE@39..40 "\n" WHITESPACE@39..40 "\n"
R_CURLY@40..41 "}" R_CURLY@40..41 "}"
WHITESPACE@41..42 "\n" WHITESPACE@41..42 "\n"
error 24..24: expected `{` error 24..24: expected a block
error 24..24: expected SEMICOLON error 24..24: expected SEMICOLON

View file

@ -0,0 +1,71 @@
SOURCE_FILE@0..83
FN_DEF@0..82
FN_KW@0..2 "fn"
WHITESPACE@2..3 " "
NAME@3..7
IDENT@3..7 "main"
PARAM_LIST@7..9
L_PAREN@7..8 "("
R_PAREN@8..9 ")"
WHITESPACE@9..10 " "
BLOCK_EXPR@10..82
L_CURLY@10..11 "{"
WHITESPACE@11..16 "\n "
EXPR_STMT@16..29
BLOCK_EXPR@16..29
L_CURLY@16..17 "{"
WHITESPACE@17..18 " "
ERROR@18..24
UNSAFE_KW@18..24 "unsafe"
WHITESPACE@24..25 " "
LITERAL@25..27
INT_NUMBER@25..27 "92"
WHITESPACE@27..28 " "
R_CURLY@28..29 "}"
WHITESPACE@29..34 "\n "
EXPR_STMT@34..46
BLOCK_EXPR@34..46
L_CURLY@34..35 "{"
WHITESPACE@35..36 " "
ERROR@36..41
ASYNC_KW@36..41 "async"
WHITESPACE@41..42 " "
LITERAL@42..44
INT_NUMBER@42..44 "92"
WHITESPACE@44..45 " "
R_CURLY@45..46 "}"
WHITESPACE@46..51 "\n "
EXPR_STMT@51..61
BLOCK_EXPR@51..61
L_CURLY@51..52 "{"
WHITESPACE@52..53 " "
EXPR_STMT@53..56
EFFECT_EXPR@53..56
TRY_KW@53..56 "try"
WHITESPACE@56..57 " "
LITERAL@57..59
INT_NUMBER@57..59 "92"
WHITESPACE@59..60 " "
R_CURLY@60..61 "}"
WHITESPACE@61..66 "\n "
BLOCK_EXPR@66..80
L_CURLY@66..67 "{"
WHITESPACE@67..68 " "
EXPR_STMT@68..75
ERROR@68..75
LABEL@68..75
LIFETIME@68..74 "\'label"
COLON@74..75 ":"
WHITESPACE@75..76 " "
LITERAL@76..78
INT_NUMBER@76..78 "92"
WHITESPACE@78..79 " "
R_CURLY@79..80 "}"
WHITESPACE@80..81 "\n"
R_CURLY@81..82 "}"
WHITESPACE@82..83 "\n"
error 24..24: expected existential, fn, trait or impl
error 41..41: expected existential, fn, trait or impl
error 56..56: expected a block
error 75..75: expected a loop
error 75..75: expected SEMICOLON

View file

@ -0,0 +1,6 @@
fn main() {
{ unsafe 92 }
{ async 92 }
{ try 92 }
{ 'label: 92 }
}

View file

@ -1,21 +0,0 @@
SOURCE_FILE@0..21
FN_DEF@0..20
FN_KW@0..2 "fn"
WHITESPACE@2..3 " "
NAME@3..6
IDENT@3..6 "foo"
PARAM_LIST@6..8
L_PAREN@6..7 "("
R_PAREN@7..8 ")"
WHITESPACE@8..9 " "
BLOCK_EXPR@9..20
L_CURLY@9..10 "{"
WHITESPACE@10..15 "\n "
EXPR_STMT@15..18
BLOCK_EXPR@15..17
L_CURLY@15..16 "{"
R_CURLY@16..17 "}"
SEMICOLON@17..18 ";"
WHITESPACE@18..19 "\n"
R_CURLY@19..20 "}"
WHITESPACE@20..21 "\n"

View file

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