mirror of
https://github.com/RustPython/Parser.git
synced 2025-08-30 07:08:14 +00:00
Break down rustpython_parser::error module
because it doesn't share any common errors but specific error for each sub module
This commit is contained in:
parent
2a8aa6f308
commit
1511b6631b
7 changed files with 338 additions and 345 deletions
|
@ -3,15 +3,14 @@
|
|||
// The lexer doesn't do any special handling of f-strings, it just treats them as
|
||||
// regular strings. Since the parser has no definition of f-string formats (Pending PEP 701)
|
||||
// we have to do the parsing here, manually.
|
||||
use itertools::Itertools;
|
||||
|
||||
use self::FStringErrorType::*;
|
||||
use crate::{
|
||||
ast::{Constant, ConversionFlag, Expr, ExprKind, Location},
|
||||
error::{FStringError, FStringErrorType, LexicalError, LexicalErrorType, ParseError},
|
||||
parser::parse_expression_located,
|
||||
token::StringKind,
|
||||
lexer::{LexicalError, LexicalErrorType},
|
||||
parser::{parse_expression_located, LalrpopError, ParseError, ParseErrorType},
|
||||
token::{StringKind, Tok},
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use std::{iter, str};
|
||||
|
||||
// unicode_name2 does not expose `MAX_NAME_LENGTH`, so we replicate that constant here, fix #3798
|
||||
|
@ -651,6 +650,107 @@ pub(crate) fn parse_strings(
|
|||
))
|
||||
}
|
||||
|
||||
// TODO: consolidate these with ParseError
|
||||
/// An error that occurred during parsing of an f-string.
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct FStringError {
|
||||
/// The type of error that occurred.
|
||||
pub error: FStringErrorType,
|
||||
/// The location of the error.
|
||||
pub location: Location,
|
||||
}
|
||||
|
||||
impl FStringError {
|
||||
/// Creates a new `FStringError` with the given error type and location.
|
||||
pub fn new(error: FStringErrorType, location: Location) -> Self {
|
||||
Self { error, location }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FStringError> for LexicalError {
|
||||
fn from(err: FStringError) -> Self {
|
||||
LexicalError {
|
||||
error: LexicalErrorType::FStringError(err.error),
|
||||
location: err.location,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents the different types of errors that can occur during parsing of an f-string.
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum FStringErrorType {
|
||||
/// Expected a right brace after an opened left brace.
|
||||
UnclosedLbrace,
|
||||
/// Expected a left brace after an ending right brace.
|
||||
UnopenedRbrace,
|
||||
/// Expected a right brace after a conversion flag.
|
||||
ExpectedRbrace,
|
||||
/// An error occurred while parsing an f-string expression.
|
||||
InvalidExpression(Box<ParseErrorType>),
|
||||
/// An invalid conversion flag was encountered.
|
||||
InvalidConversionFlag,
|
||||
/// An empty expression was encountered.
|
||||
EmptyExpression,
|
||||
/// An opening delimiter was not closed properly.
|
||||
MismatchedDelimiter(char, char),
|
||||
/// Too many nested expressions in an f-string.
|
||||
ExpressionNestedTooDeeply,
|
||||
/// The f-string expression cannot include the given character.
|
||||
ExpressionCannotInclude(char),
|
||||
/// A single right brace was encountered.
|
||||
SingleRbrace,
|
||||
/// A closing delimiter was not opened properly.
|
||||
Unmatched(char),
|
||||
// TODO: Test this case.
|
||||
/// Unterminated string.
|
||||
UnterminatedString,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for FStringErrorType {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
FStringErrorType::UnclosedLbrace => write!(f, "expecting '}}'"),
|
||||
FStringErrorType::UnopenedRbrace => write!(f, "Unopened '}}'"),
|
||||
FStringErrorType::ExpectedRbrace => write!(f, "Expected '}}' after conversion flag."),
|
||||
FStringErrorType::InvalidExpression(error) => {
|
||||
write!(f, "{error}")
|
||||
}
|
||||
FStringErrorType::InvalidConversionFlag => write!(f, "invalid conversion character"),
|
||||
FStringErrorType::EmptyExpression => write!(f, "empty expression not allowed"),
|
||||
FStringErrorType::MismatchedDelimiter(first, second) => write!(
|
||||
f,
|
||||
"closing parenthesis '{second}' does not match opening parenthesis '{first}'"
|
||||
),
|
||||
FStringErrorType::SingleRbrace => write!(f, "single '}}' is not allowed"),
|
||||
FStringErrorType::Unmatched(delim) => write!(f, "unmatched '{delim}'"),
|
||||
FStringErrorType::ExpressionNestedTooDeeply => {
|
||||
write!(f, "expressions nested too deeply")
|
||||
}
|
||||
FStringErrorType::UnterminatedString => {
|
||||
write!(f, "unterminated string")
|
||||
}
|
||||
FStringErrorType::ExpressionCannotInclude(c) => {
|
||||
if *c == '\\' {
|
||||
write!(f, "f-string expression part cannot include a backslash")
|
||||
} else {
|
||||
write!(f, "f-string expression part cannot include '{c}'s")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FStringError> for LalrpopError<Location, Tok, LexicalError> {
|
||||
fn from(err: FStringError) -> Self {
|
||||
lalrpop_util::ParseError::User {
|
||||
error: LexicalError {
|
||||
error: LexicalErrorType::FStringError(err.error),
|
||||
location: err.location,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue