1- //! Define internal parse error types
2- //! The goal is to provide a matching and a safe error API, maksing errors from LALR
1+ //! Error types for the parser.
2+ //!
3+ //! These types are used to represent errors that occur during lexing and parsing and are
4+ //! returned by the `parse_*` functions in the [parser] module and the iterator in the
5+ //! [lexer] implementation.
6+ //!
7+ //! [parser]: crate::parser
8+ //! [lexer]: crate::lexer
39
10+ // Define internal parse error types.
11+ // The goal is to provide a matching and a safe error API, masking errors from LALR
412use crate :: { ast:: Location , token:: Tok } ;
513use lalrpop_util:: ParseError as LalrpopError ;
614use std:: fmt;
715
8- /// Represents an error during lexical scanning .
16+ /// Represents an error during lexing .
917#[ derive( Debug , PartialEq ) ]
1018pub struct LexicalError {
19+ /// The type of error that occurred.
1120 pub error : LexicalErrorType ,
21+ /// The location of the error.
1222 pub location : Location ,
1323}
1424
1525impl LexicalError {
26+ /// Creates a new `LexicalError` with the given error type and location.
1627 pub fn new ( error : LexicalErrorType , location : Location ) -> Self {
1728 Self { error, location }
1829 }
1930}
2031
32+ /// Represents the different types of errors that can occur during lexing.
2133#[ derive( Debug , PartialEq ) ]
2234pub enum LexicalErrorType {
35+ // TODO: Can probably be removed, the places it is used seem to be able
36+ // to use the `UnicodeError` variant instead.
37+ #[ doc( hidden) ]
2338 StringError ,
39+ // TODO: Should take a start/end position to report.
40+ /// Decoding of a unicode escape sequence in a string literal failed.
2441 UnicodeError ,
42+ /// The nesting of brackets/braces/parentheses is not balanced.
2543 NestingError ,
44+ /// The indentation is not consistent.
2645 IndentationError ,
46+ /// Inconsistent use of tabs and spaces.
2747 TabError ,
48+ /// Encountered a tab after a space.
2849 TabsAfterSpaces ,
50+ /// A non-default argument follows a default argument.
2951 DefaultArgumentError ,
52+ /// A duplicate argument was found in a function definition.
3053 DuplicateArgumentError ( String ) ,
54+ /// A positional argument follows a keyword argument.
3155 PositionalArgumentError ,
56+ /// An iterable argument unpacking `*args` follows keyword argument unpacking `**kwargs`.
3257 UnpackedArgumentError ,
58+ /// A keyword argument was repeated.
3359 DuplicateKeywordArgumentError ( String ) ,
60+ /// An unrecognized token was encountered.
3461 UnrecognizedToken { tok : char } ,
62+ /// An f-string error containing the [`FStringErrorType`].
3563 FStringError ( FStringErrorType ) ,
64+ /// An unexpected character was encountered after a line continuation.
3665 LineContinuationError ,
66+ /// An unexpected end of file was encountered.
3767 Eof ,
68+ /// An unexpected error occurred.
3869 OtherError ( String ) ,
3970}
4071
@@ -85,13 +116,17 @@ impl fmt::Display for LexicalErrorType {
85116}
86117
87118// TODO: consolidate these with ParseError
119+ /// An error that occurred during parsing of an f-string.
88120#[ derive( Debug , PartialEq ) ]
89121pub struct FStringError {
122+ /// The type of error that occurred.
90123 pub error : FStringErrorType ,
124+ /// The location of the error.
91125 pub location : Location ,
92126}
93127
94128impl FStringError {
129+ /// Creates a new `FStringError` with the given error type and location.
95130 pub fn new ( error : FStringErrorType , location : Location ) -> Self {
96131 Self { error, location }
97132 }
@@ -106,19 +141,33 @@ impl From<FStringError> for LexicalError {
106141 }
107142}
108143
144+ /// Represents the different types of errors that can occur during parsing of an f-string.
109145#[ derive( Debug , PartialEq ) ]
110146pub enum FStringErrorType {
147+ /// Expected a right brace after an opened left brace.
111148 UnclosedLbrace ,
149+ /// Expected a left brace after an ending right brace.
112150 UnopenedRbrace ,
151+ /// Expected a right brace after a conversion flag.
113152 ExpectedRbrace ,
153+ /// An error occurred while parsing an f-string expression.
114154 InvalidExpression ( Box < ParseErrorType > ) ,
155+ /// An invalid conversion flag was encountered.
115156 InvalidConversionFlag ,
157+ /// An empty expression was encountered.
116158 EmptyExpression ,
159+ /// An opening delimiter was not closed properly.
117160 MismatchedDelimiter ( char , char ) ,
161+ /// Too many nested expressions in an f-string.
118162 ExpressionNestedTooDeeply ,
163+ /// The f-string expression cannot include the given character.
119164 ExpressionCannotInclude ( char ) ,
165+ /// A single right brace was encountered.
120166 SingleRbrace ,
167+ /// A closing delimiter was not opened properly.
121168 Unmatched ( char ) ,
169+ // TODO: Test this case.
170+ /// Unterminated string.
122171 UnterminatedString ,
123172}
124173
@@ -167,9 +216,10 @@ impl From<FStringError> for LalrpopError<Location, Tok, LexicalError> {
167216 }
168217}
169218
170- /// Represents an error during parsing
219+ /// Represents an error during parsing.
171220pub type ParseError = rustpython_compiler_core:: BaseError < ParseErrorType > ;
172221
222+ /// Represents the different types of errors that can occur during parsing.
173223#[ derive( Debug , PartialEq , thiserror:: Error ) ]
174224pub enum ParseErrorType {
175225 /// Parser encountered an unexpected end of input
@@ -180,11 +230,12 @@ pub enum ParseErrorType {
180230 InvalidToken ,
181231 /// Parser encountered an unexpected token
182232 UnrecognizedToken ( Tok , Option < String > ) ,
183- /// Maps to `User` type from `lalrpop-util`
233+ // Maps to `User` type from `lalrpop-util`
234+ /// Parser encountered an error during lexing.
184235 Lexical ( LexicalErrorType ) ,
185236}
186237
187- /// Convert `lalrpop_util::ParseError` to our internal type
238+ // Convert `lalrpop_util::ParseError` to our internal type
188239pub ( crate ) fn parse_error_from_lalrpop (
189240 err : LalrpopError < Location , Tok , LexicalError > ,
190241 source_path : & str ,
@@ -258,6 +309,7 @@ impl fmt::Display for ParseErrorType {
258309}
259310
260311impl ParseErrorType {
312+ /// Returns true if the error is an indentation error.
261313 pub fn is_indentation_error ( & self ) -> bool {
262314 match self {
263315 ParseErrorType :: Lexical ( LexicalErrorType :: IndentationError ) => true ,
@@ -267,6 +319,8 @@ impl ParseErrorType {
267319 _ => false ,
268320 }
269321 }
322+
323+ /// Returns true if the error is a tab error.
270324 pub fn is_tab_error ( & self ) -> bool {
271325 matches ! (
272326 self ,
0 commit comments