parameter parsing does not destroy blocks

This commit is contained in:
Aleksey Kladov 2018-08-24 20:50:37 +03:00
parent b0aac1ca98
commit f104458d45
10 changed files with 70 additions and 4 deletions

View File

@ -13,7 +13,7 @@ use super::*;
// let _ = b"e";
// let _ = br"f";
// }
const LITERAL_FIRST: TokenSet =
pub(crate) const LITERAL_FIRST: TokenSet =
token_set![TRUE_KW, FALSE_KW, INT_NUMBER, FLOAT_NUMBER, BYTE, CHAR,
STRING, RAW_STRING, BYTE_STRING, RAW_BYTE_STRING];

View File

@ -1,7 +1,7 @@
mod atom;
use super::*;
pub(super) use self::atom::literal;
pub(super) use self::atom::{literal, LITERAL_FIRST};
const EXPR_FIRST: TokenSet = LHS_FIRST;

View File

@ -250,8 +250,10 @@ fn function(p: &mut Parser, flavor: ItemFlavor) {
// test fn_decl
// trait T { fn foo(); }
if !p.eat(SEMI) {
if p.at(L_CURLY) {
expressions::block(p);
} else {
p.expect(SEMI);
}
}

View File

@ -48,6 +48,10 @@ fn list_(p: &mut Parser, flavor: Flavor) {
opt_self_param(p);
}
while !p.at(EOF) && !p.at(ket) {
if !VALUE_PARAMETER_FIRST.contains(p.current()) {
p.error("expected value parameter");
break;
}
value_parameter(p, flavor);
if !p.at(ket) {
p.expect(COMMA);
@ -57,6 +61,13 @@ fn list_(p: &mut Parser, flavor: Flavor) {
m.complete(p, PARAM_LIST);
}
const VALUE_PARAMETER_FIRST: TokenSet =
token_set_union![
patterns::PATTERN_FIRST,
types::TYPE_FIRST,
];
fn value_parameter(p: &mut Parser, flavor: Flavor) {
let m = p.start();
match flavor {

View File

@ -1,5 +1,8 @@
use super::*;
pub(super) const PATH_FIRST: TokenSet =
token_set![IDENT, SELF_KW, SUPER_KW, COLONCOLON, L_ANGLE];
pub(super) fn is_path_start(p: &Parser) -> bool {
match p.current() {
IDENT | SELF_KW | SUPER_KW | COLONCOLON => true,

View File

@ -1,5 +1,12 @@
use super::*;
pub(super) const PATTERN_FIRST: TokenSet =
token_set_union![
token_set![REF_KW, MUT_KW, L_PAREN, L_BRACK, AMP],
expressions::LITERAL_FIRST,
paths::PATH_FIRST,
];
pub(super) fn pattern(p: &mut Parser) {
if let Some(lhs) = atom_pat(p) {
// test range_pat

View File

@ -1,5 +1,13 @@
use super::*;
pub(super) const TYPE_FIRST: TokenSet =
token_set_union![
token_set![
L_PAREN, EXCL, STAR, L_BRACK, AMP, UNDERSCORE, FN_KW, UNSAFE_KW, EXTERN_KW, FOR_KW, IMPL_KW, DYN_KW, L_ANGLE,
],
paths::PATH_FIRST,
];
pub(super) fn type_(p: &mut Parser) {
match p.current() {
L_PAREN => paren_or_tuple_type(p),

View File

@ -58,6 +58,10 @@ pub fn parse(text: &str) -> SyntaxNode {
res
}
#[cfg(not(debug_assertions))]
fn validate_block_structure(_: SyntaxNodeRef) {}
#[cfg(debug_assertions)]
fn validate_block_structure(root: SyntaxNodeRef) {
let mut stack = Vec::new();
for node in algo::walk::preorder(root) {
@ -67,7 +71,12 @@ fn validate_block_structure(root: SyntaxNodeRef) {
}
SyntaxKind::R_CURLY => {
if let Some(pair) = stack.pop() {
assert_eq!(node.parent(), pair.parent());
assert_eq!(
node.parent(),
pair.parent(),
"unpaired curleys:\n{}",
utils::dump_tree(root),
);
assert!(
node.next_sibling().is_none() && pair.prev_sibling().is_none(),
"floating curlys at {:?}\nfile:\n{}\nerror:\n{}\n",

View File

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

View File

@ -0,0 +1,24 @@
FILE@[0; 14)
FN_DEF@[0; 7)
FN_KW@[0; 2)
WHITESPACE@[2; 3)
NAME@[3; 6)
IDENT@[3; 6) "foo"
PARAM_LIST@[6; 7)
L_PAREN@[6; 7)
err: `expected value parameter`
err: `expected R_PAREN`
err: `expected SEMI`
err: `expected an item`
ERROR@[7; 8)
R_CURLY@[7; 8)
err: `expected an item`
ERROR@[8; 9)
R_PAREN@[8; 9)
WHITESPACE@[9; 10)
err: `expected an item`
ERROR@[10; 13)
L_CURLY@[10; 11)
WHITESPACE@[11; 12)
R_CURLY@[12; 13)
WHITESPACE@[13; 14)