Integrate ParseError to compiler-core::Error

This commit is contained in:
Jeong YunWon 2022-08-22 09:07:15 +09:00
parent 904fc477f1
commit 2b7bf79d29
5 changed files with 67 additions and 32 deletions

22
core/src/error.rs Normal file
View file

@ -0,0 +1,22 @@
use crate::Location;
#[derive(Debug, PartialEq, Eq)]
pub struct Error<T> {
pub error: T,
pub location: Location,
pub source_path: String,
}
impl<T> std::ops::Deref for Error<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.error
}
}
impl<T> Error<T> {
pub fn error(self) -> T {
self.error
}
}

View file

@ -2,9 +2,11 @@
#![doc(html_root_url = "https://docs.rs/rustpython-compiler-core/")] #![doc(html_root_url = "https://docs.rs/rustpython-compiler-core/")]
mod bytecode; mod bytecode;
mod error;
mod location; mod location;
mod mode; mod mode;
pub use bytecode::*; pub use bytecode::*;
pub use error::Error;
pub use location::Location; pub use location::Location;
pub use mode::Mode; pub use mode::Mode;

View file

@ -16,6 +16,7 @@ tiny-keccak = { version = "2", features = ["sha3"] }
[dependencies] [dependencies]
rustpython-ast = { path = "../ast" } rustpython-ast = { path = "../ast" }
rustpython-compiler-core = { path = "../core" }
ahash = "0.7.6" ahash = "0.7.6"
itertools = "0.10.3" itertools = "0.10.3"

View file

@ -118,11 +118,7 @@ impl From<FStringError> for LalrpopError<Location, Tok, LexicalError> {
/// Represents an error during parsing /// Represents an error during parsing
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub struct ParseError { pub struct ParseError(rustpython_compiler_core::Error<ParseErrorType>);
pub error: ParseErrorType,
pub location: Location,
pub source_path: String,
}
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum ParseErrorType { pub enum ParseErrorType {
@ -138,8 +134,28 @@ pub enum ParseErrorType {
Lexical(LexicalErrorType), Lexical(LexicalErrorType),
} }
impl From<ParseError> for rustpython_compiler_core::Error<ParseErrorType> {
fn from(err: ParseError) -> Self {
err.0
}
}
impl From<ParseError> for ParseErrorType {
fn from(err: ParseError) -> Self {
err.0.error
}
}
/// Convert `lalrpop_util::ParseError` to our internal type /// Convert `lalrpop_util::ParseError` to our internal type
impl ParseError { impl ParseError {
fn new(error: ParseErrorType, location: Location, source_path: String) -> Self {
Self(rustpython_compiler_core::Error {
error,
location,
source_path,
})
}
pub(crate) fn from_lalrpop( pub(crate) fn from_lalrpop(
err: LalrpopError<Location, Tok, LexicalError>, err: LalrpopError<Location, Tok, LexicalError>,
source_path: &str, source_path: &str,
@ -147,36 +163,30 @@ impl ParseError {
let source_path = source_path.to_owned(); let source_path = source_path.to_owned();
match err { match err {
// TODO: Are there cases where this isn't an EOF? // TODO: Are there cases where this isn't an EOF?
LalrpopError::InvalidToken { location } => ParseError { LalrpopError::InvalidToken { location } => {
error: ParseErrorType::Eof, ParseError::new(ParseErrorType::Eof, location, source_path)
location, }
LalrpopError::ExtraToken { token } => {
ParseError::new(ParseErrorType::ExtraToken(token.1), token.0, source_path)
}
LalrpopError::User { error } => ParseError::new(
ParseErrorType::Lexical(error.error),
error.location,
source_path, source_path,
}, ),
LalrpopError::ExtraToken { token } => ParseError {
error: ParseErrorType::ExtraToken(token.1),
location: token.0,
source_path,
},
LalrpopError::User { error } => ParseError {
error: ParseErrorType::Lexical(error.error),
location: error.location,
source_path,
},
LalrpopError::UnrecognizedToken { token, expected } => { LalrpopError::UnrecognizedToken { token, expected } => {
// Hacky, but it's how CPython does it. See PyParser_AddToken, // Hacky, but it's how CPython does it. See PyParser_AddToken,
// in particular "Only one possible expected token" comment. // in particular "Only one possible expected token" comment.
let expected = (expected.len() == 1).then(|| expected[0].clone()); let expected = (expected.len() == 1).then(|| expected[0].clone());
ParseError { ParseError::new(
error: ParseErrorType::UnrecognizedToken(token.1, expected), ParseErrorType::UnrecognizedToken(token.1, expected),
location: token.0, token.0,
source_path, source_path,
} )
}
LalrpopError::UnrecognizedEOF { location, .. } => {
ParseError::new(ParseErrorType::Eof, location, source_path)
} }
LalrpopError::UnrecognizedEOF { location, .. } => ParseError {
error: ParseErrorType::Eof,
location,
source_path,
},
} }
} }
} }
@ -229,9 +239,9 @@ impl ParseErrorType {
} }
impl std::ops::Deref for ParseError { impl std::ops::Deref for ParseError {
type Target = ParseErrorType; type Target = rustpython_compiler_core::Error<ParseErrorType>;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
&self.error &self.0
} }
} }

View file

@ -186,7 +186,7 @@ impl<'a> FStringParser<'a> {
vec![self.expr(ExprKind::FormattedValue { vec![self.expr(ExprKind::FormattedValue {
value: Box::new( value: Box::new(
parse_fstring_expr(&expression) parse_fstring_expr(&expression)
.map_err(|e| InvalidExpression(Box::new(e.error)))?, .map_err(|e| InvalidExpression(Box::new(e.into())))?,
), ),
conversion: conversion as _, conversion: conversion as _,
format_spec: spec, format_spec: spec,
@ -204,7 +204,7 @@ impl<'a> FStringParser<'a> {
self.expr(ExprKind::FormattedValue { self.expr(ExprKind::FormattedValue {
value: Box::new( value: Box::new(
parse_fstring_expr(&expression) parse_fstring_expr(&expression)
.map_err(|e| InvalidExpression(Box::new(e.error)))?, .map_err(|e| InvalidExpression(Box::new(e.into())))?,
), ),
conversion: (if conversion == ConversionFlag::None && spec.is_none() conversion: (if conversion == ConversionFlag::None && spec.is_none()
{ {