Improve readability of the parser code
This commit is contained in:
parent
00a0125372
commit
2a41b2cd94
@ -416,14 +416,12 @@ fn delimited(
|
|||||||
if !parser(p) {
|
if !parser(p) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if !p.at(delim) {
|
if !p.eat(delim) {
|
||||||
if p.at_ts(first_set) {
|
if p.at_ts(first_set) {
|
||||||
p.error(format!("expected {:?}", delim));
|
p.error(format!("expected {:?}", delim));
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
p.bump(delim);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p.expect(ket);
|
p.expect(ket);
|
||||||
|
@ -211,9 +211,8 @@ fn current_op(p: &Parser<'_>) -> (u8, SyntaxKind, Associativity) {
|
|||||||
T![>] if p.at(T![>>]) => (9, T![>>], Left),
|
T![>] if p.at(T![>>]) => (9, T![>>], Left),
|
||||||
T![>] if p.at(T![>=]) => (5, T![>=], Left),
|
T![>] if p.at(T![>=]) => (5, T![>=], Left),
|
||||||
T![>] => (5, T![>], Left),
|
T![>] => (5, T![>], Left),
|
||||||
T![=] if p.at(T![=>]) => NOT_AN_OP,
|
|
||||||
T![=] if p.at(T![==]) => (5, T![==], Left),
|
T![=] if p.at(T![==]) => (5, T![==], Left),
|
||||||
T![=] => (1, T![=], Right),
|
T![=] if !p.at(T![=>]) => (1, T![=], Right),
|
||||||
T![<] if p.at(T![<=]) => (5, T![<=], Left),
|
T![<] if p.at(T![<=]) => (5, T![<=], Left),
|
||||||
T![<] if p.at(T![<<=]) => (1, T![<<=], Right),
|
T![<] if p.at(T![<<=]) => (1, T![<<=], Right),
|
||||||
T![<] if p.at(T![<<]) => (9, T![<<], Left),
|
T![<] if p.at(T![<<]) => (9, T![<<], Left),
|
||||||
@ -247,7 +246,7 @@ fn current_op(p: &Parser<'_>) -> (u8, SyntaxKind, Associativity) {
|
|||||||
fn expr_bp(
|
fn expr_bp(
|
||||||
p: &mut Parser<'_>,
|
p: &mut Parser<'_>,
|
||||||
m: Option<Marker>,
|
m: Option<Marker>,
|
||||||
mut r: Restrictions,
|
r: Restrictions,
|
||||||
bp: u8,
|
bp: u8,
|
||||||
) -> Option<(CompletedMarker, BlockLike)> {
|
) -> Option<(CompletedMarker, BlockLike)> {
|
||||||
let m = m.unwrap_or_else(|| {
|
let m = m.unwrap_or_else(|| {
|
||||||
@ -295,10 +294,6 @@ fn expr_bp(
|
|||||||
let m = lhs.precede(p);
|
let m = lhs.precede(p);
|
||||||
p.bump(op);
|
p.bump(op);
|
||||||
|
|
||||||
// test binop_resets_statementness
|
|
||||||
// fn f() { v = {1}&2; }
|
|
||||||
r = Restrictions { prefer_stmt: false, ..r };
|
|
||||||
|
|
||||||
if is_range {
|
if is_range {
|
||||||
// test postfix_range
|
// test postfix_range
|
||||||
// fn foo() {
|
// fn foo() {
|
||||||
@ -319,6 +314,9 @@ fn expr_bp(
|
|||||||
Associativity::Left => op_bp + 1,
|
Associativity::Left => op_bp + 1,
|
||||||
Associativity::Right => op_bp,
|
Associativity::Right => op_bp,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// test binop_resets_statementness
|
||||||
|
// fn f() { v = {1}&2; }
|
||||||
expr_bp(p, None, Restrictions { prefer_stmt: false, ..r }, op_bp);
|
expr_bp(p, None, Restrictions { prefer_stmt: false, ..r }, op_bp);
|
||||||
lhs = m.complete(p, if is_range { RANGE_EXPR } else { BIN_EXPR });
|
lhs = m.complete(p, if is_range { RANGE_EXPR } else { BIN_EXPR });
|
||||||
}
|
}
|
||||||
@ -345,7 +343,7 @@ fn lhs(p: &mut Parser<'_>, r: Restrictions) -> Option<(CompletedMarker, BlockLik
|
|||||||
T![&] => {
|
T![&] => {
|
||||||
m = p.start();
|
m = p.start();
|
||||||
p.bump(T![&]);
|
p.bump(T![&]);
|
||||||
if p.at_contextual_kw(T![raw]) && (p.nth_at(1, T![mut]) || p.nth_at(1, T![const])) {
|
if p.at_contextual_kw(T![raw]) && [T![mut], T![const]].contains(&p.nth(1)) {
|
||||||
p.bump_remap(T![raw]);
|
p.bump_remap(T![raw]);
|
||||||
p.bump_any();
|
p.bump_any();
|
||||||
} else {
|
} else {
|
||||||
|
@ -147,7 +147,7 @@ pub(super) fn atom_expr(
|
|||||||
T![async] if la == T![move] && p.nth(2) == T!['{'] => {
|
T![async] if la == T![move] && p.nth(2) == T!['{'] => {
|
||||||
let m = p.start();
|
let m = p.start();
|
||||||
p.bump(T![async]);
|
p.bump(T![async]);
|
||||||
p.eat(T![move]);
|
p.bump(T![move]);
|
||||||
stmt_list(p);
|
stmt_list(p);
|
||||||
m.complete(p, BLOCK_EXPR)
|
m.complete(p, BLOCK_EXPR)
|
||||||
}
|
}
|
||||||
@ -390,8 +390,7 @@ fn if_expr(p: &mut Parser<'_>) -> CompletedMarker {
|
|||||||
p.bump(T![if]);
|
p.bump(T![if]);
|
||||||
expr_no_struct(p);
|
expr_no_struct(p);
|
||||||
block_expr(p);
|
block_expr(p);
|
||||||
if p.at(T![else]) {
|
if p.eat(T![else]) {
|
||||||
p.bump(T![else]);
|
|
||||||
if p.at(T![if]) {
|
if p.at(T![if]) {
|
||||||
if_expr(p);
|
if_expr(p);
|
||||||
} else {
|
} else {
|
||||||
|
@ -170,7 +170,7 @@ fn type_bound(p: &mut Parser<'_>) -> bool {
|
|||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
if paths::is_use_path_start(p) {
|
if paths::is_use_path_start(p) {
|
||||||
types::path_type_(p, false);
|
types::path_type_bounds(p, false);
|
||||||
} else {
|
} else {
|
||||||
m.abandon(p);
|
m.abandon(p);
|
||||||
return false;
|
return false;
|
||||||
|
@ -156,27 +156,19 @@ pub(super) fn opt_item(p: &mut Parser<'_>, m: Marker) -> Result<(), Marker> {
|
|||||||
// impl T for Foo {
|
// impl T for Foo {
|
||||||
// default async fn foo() {}
|
// default async fn foo() {}
|
||||||
// }
|
// }
|
||||||
T![async] => {
|
T![async]
|
||||||
let mut maybe_fn = p.nth(2);
|
if p.nth_at(2, T![fn]) || (p.nth_at(2, T![unsafe]) && p.nth_at(3, T![fn])) =>
|
||||||
let is_unsafe = if matches!(maybe_fn, T![unsafe]) {
|
{
|
||||||
// test default_async_unsafe_fn
|
p.bump_remap(T![default]);
|
||||||
// impl T for Foo {
|
p.bump(T![async]);
|
||||||
// default async unsafe fn foo() {}
|
|
||||||
// }
|
|
||||||
maybe_fn = p.nth(3);
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
};
|
|
||||||
|
|
||||||
if matches!(maybe_fn, T![fn]) {
|
// test default_async_unsafe_fn
|
||||||
p.bump_remap(T![default]);
|
// impl T for Foo {
|
||||||
p.bump(T![async]);
|
// default async unsafe fn foo() {}
|
||||||
if is_unsafe {
|
// }
|
||||||
p.bump(T![unsafe]);
|
p.eat(T![unsafe]);
|
||||||
}
|
|
||||||
has_mods = true;
|
has_mods = true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
@ -419,11 +411,9 @@ fn fn_(p: &mut Parser<'_>, m: Marker) {
|
|||||||
// fn foo<T>() where T: Copy {}
|
// fn foo<T>() where T: Copy {}
|
||||||
generic_params::opt_where_clause(p);
|
generic_params::opt_where_clause(p);
|
||||||
|
|
||||||
if p.at(T![;]) {
|
// test fn_decl
|
||||||
// test fn_decl
|
// trait T { fn foo(); }
|
||||||
// trait T { fn foo(); }
|
if !p.eat(T![;]) {
|
||||||
p.bump(T![;]);
|
|
||||||
} else {
|
|
||||||
expressions::block_expr(p);
|
expressions::block_expr(p);
|
||||||
}
|
}
|
||||||
m.complete(p, FN);
|
m.complete(p, FN);
|
||||||
|
@ -119,11 +119,11 @@ fn not_a_qualified_path(p: &Parser<'_>) -> bool {
|
|||||||
// we disambiguate it in favor of generics (`impl<T> ::absolute::Path<T> { ... }`)
|
// we disambiguate it in favor of generics (`impl<T> ::absolute::Path<T> { ... }`)
|
||||||
// because this is what almost always expected in practice, qualified paths in impls
|
// because this is what almost always expected in practice, qualified paths in impls
|
||||||
// (`impl <Type>::AssocTy { ... }`) aren't even allowed by type checker at the moment.
|
// (`impl <Type>::AssocTy { ... }`) aren't even allowed by type checker at the moment.
|
||||||
if p.nth(1) == T![#] || p.nth(1) == T![>] || p.nth(1) == T![const] {
|
if [T![#], T![>], T![const]].contains(&p.nth(1)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
(p.nth(1) == LIFETIME_IDENT || p.nth(1) == IDENT)
|
([LIFETIME_IDENT, IDENT].contains(&p.nth(1)))
|
||||||
&& (p.nth(2) == T![>] || p.nth(2) == T![,] || p.nth(2) == T![:] || p.nth(2) == T![=])
|
&& ([T![>], T![,], T![:], T![=]].contains(&p.nth(2)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// test_err impl_type
|
// test_err impl_type
|
||||||
|
@ -76,19 +76,16 @@ fn list_(p: &mut Parser<'_>, flavor: Flavor) {
|
|||||||
m.abandon(p);
|
m.abandon(p);
|
||||||
if p.eat(T![,]) {
|
if p.eat(T![,]) {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
param(p, m, flavor);
|
param(p, m, flavor);
|
||||||
if !p.at(T![,]) {
|
if !p.eat(T![,]) {
|
||||||
if p.at_ts(PARAM_FIRST.union(ATTRIBUTE_FIRST)) {
|
if p.at_ts(PARAM_FIRST.union(ATTRIBUTE_FIRST)) {
|
||||||
p.error("expected `,`");
|
p.error("expected `,`");
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
p.bump(T![,]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,9 +255,7 @@ fn is_literal_pat_start(p: &Parser<'_>) -> bool {
|
|||||||
fn literal_pat(p: &mut Parser<'_>) -> CompletedMarker {
|
fn literal_pat(p: &mut Parser<'_>) -> CompletedMarker {
|
||||||
assert!(is_literal_pat_start(p));
|
assert!(is_literal_pat_start(p));
|
||||||
let m = p.start();
|
let m = p.start();
|
||||||
if p.at(T![-]) {
|
p.eat(T![-]);
|
||||||
p.bump(T![-]);
|
|
||||||
}
|
|
||||||
expressions::literal(p);
|
expressions::literal(p);
|
||||||
m.complete(p, LITERAL_PAT)
|
m.complete(p, LITERAL_PAT)
|
||||||
}
|
}
|
||||||
@ -468,14 +466,12 @@ fn slice_pat(p: &mut Parser<'_>) -> CompletedMarker {
|
|||||||
fn pat_list(p: &mut Parser<'_>, ket: SyntaxKind) {
|
fn pat_list(p: &mut Parser<'_>, ket: SyntaxKind) {
|
||||||
while !p.at(EOF) && !p.at(ket) {
|
while !p.at(EOF) && !p.at(ket) {
|
||||||
pattern_top(p);
|
pattern_top(p);
|
||||||
if !p.at(T![,]) {
|
if !p.eat(T![,]) {
|
||||||
if p.at_ts(PAT_TOP_FIRST) {
|
if p.at_ts(PAT_TOP_FIRST) {
|
||||||
p.error(format!("expected {:?}, got {:?}", T![,], p.current()));
|
p.error(format!("expected {:?}, got {:?}", T![,], p.current()));
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
p.bump(T![,]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ fn type_with_bounds_cond(p: &mut Parser<'_>, allow_bounds: bool) {
|
|||||||
T![impl] => impl_trait_type(p),
|
T![impl] => impl_trait_type(p),
|
||||||
T![dyn] => dyn_trait_type(p),
|
T![dyn] => dyn_trait_type(p),
|
||||||
// Some path types are not allowed to have bounds (no plus)
|
// Some path types are not allowed to have bounds (no plus)
|
||||||
T![<] => path_type_(p, allow_bounds),
|
T![<] => path_type_bounds(p, allow_bounds),
|
||||||
_ if paths::is_path_start(p) => path_or_macro_type_(p, allow_bounds),
|
_ if paths::is_path_start(p) => path_or_macro_type_(p, allow_bounds),
|
||||||
LIFETIME_IDENT if p.nth_at(1, T![+]) => bare_dyn_trait_type(p),
|
LIFETIME_IDENT if p.nth_at(1, T![+]) => bare_dyn_trait_type(p),
|
||||||
_ => {
|
_ => {
|
||||||
@ -294,7 +294,7 @@ fn bare_dyn_trait_type(p: &mut Parser<'_>) {
|
|||||||
// type C = self::Foo;
|
// type C = self::Foo;
|
||||||
// type D = super::Foo;
|
// type D = super::Foo;
|
||||||
pub(super) fn path_type(p: &mut Parser<'_>) {
|
pub(super) fn path_type(p: &mut Parser<'_>) {
|
||||||
path_type_(p, true);
|
path_type_bounds(p, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// test macro_call_type
|
// test macro_call_type
|
||||||
@ -323,7 +323,7 @@ fn path_or_macro_type_(p: &mut Parser<'_>, allow_bounds: bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn path_type_(p: &mut Parser<'_>, allow_bounds: bool) {
|
pub(super) fn path_type_bounds(p: &mut Parser<'_>, allow_bounds: bool) {
|
||||||
assert!(paths::is_path_start(p));
|
assert!(paths::is_path_start(p));
|
||||||
let m = p.start();
|
let m = p.start();
|
||||||
paths::type_path(p);
|
paths::type_path(p);
|
||||||
|
@ -250,12 +250,9 @@ impl<'t> Parser<'t> {
|
|||||||
|
|
||||||
/// Create an error node and consume the next token.
|
/// Create an error node and consume the next token.
|
||||||
pub(crate) fn err_recover(&mut self, message: &str, recovery: TokenSet) {
|
pub(crate) fn err_recover(&mut self, message: &str, recovery: TokenSet) {
|
||||||
match self.current() {
|
if matches!(self.current(), T!['{'] | T!['}']) {
|
||||||
T!['{'] | T!['}'] => {
|
self.error(message);
|
||||||
self.error(message);
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.at_ts(recovery) {
|
if self.at_ts(recovery) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user