use crate::diagnostics::DiagnosticKind;
use crate::parser::Parser;
use crate::parser::cst::SyntaxKind;
use crate::parser::cst::token_sets::EXPR_FIRST_TOKENS;
impl Parser<'_, '_> {
pub(crate) fn parse_expr_or_error(&mut self) -> bool {
if self.currently_is_one_of(EXPR_FIRST_TOKENS) {
self.parse_expr();
return true;
}
if self.currently_is(SyntaxKind::At) {
self.error_and_bump(DiagnosticKind::CaptureWithoutTarget);
return false;
}
if self.currently_is(SyntaxKind::TsPredicate) {
self.error_and_bump(DiagnosticKind::UnsupportedPredicate);
return false;
}
self.error_and_bump_with_hint(
DiagnosticKind::UnexpectedToken,
"try `(node)`, `[a b]`, `{a b}`, `\"literal\"`, or `_`",
);
false
}
pub(crate) fn parse_expr(&mut self) {
self.parse_expr_inner(true)
}
pub(crate) fn parse_expr_no_suffix(&mut self) {
self.parse_expr_inner(false)
}
fn parse_expr_inner(&mut self, with_suffix: bool) {
if !self.enter_recursion() {
self.start_node(SyntaxKind::Error);
while !self.should_stop() {
self.bump();
}
self.finish_node();
return;
}
let checkpoint = self.checkpoint();
match self.current() {
SyntaxKind::ParenOpen => self.parse_tree(),
SyntaxKind::BracketOpen => self.parse_alt(),
SyntaxKind::BraceOpen => self.parse_seq(),
SyntaxKind::Underscore => self.parse_wildcard(),
SyntaxKind::SingleQuote | SyntaxKind::DoubleQuote => self.parse_str(),
SyntaxKind::Dot => self.parse_anchor(),
SyntaxKind::Negation | SyntaxKind::Minus => self.parse_negated_field(),
SyntaxKind::Id => self.parse_tree_or_field(),
SyntaxKind::KwError | SyntaxKind::KwMissing => {
self.error_and_bump(DiagnosticKind::ErrorMissingOutsideParens);
}
_ => {
self.error_and_bump(DiagnosticKind::UnexpectedToken);
}
}
if with_suffix {
self.try_parse_quantifier(checkpoint);
self.try_parse_capture(checkpoint);
}
self.exit_recursion();
}
}