Skip to content

Commit 0e74d16

Browse files
committed
Pass ParseError location to CompileError
1 parent ef1d543 commit 0e74d16

File tree

4 files changed

+62
-51
lines changed

4 files changed

+62
-51
lines changed

compiler/src/error.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rustpython_parser::error::ParseError;
1+
use rustpython_parser::error::{ParseError, ParseErrorType};
22
use rustpython_parser::lexer::Location;
33

44
use std::error::Error;
@@ -13,8 +13,8 @@ pub struct CompileError {
1313
impl From<ParseError> for CompileError {
1414
fn from(error: ParseError) -> Self {
1515
CompileError {
16-
error: CompileErrorType::Parse(error),
17-
location: Default::default(), // TODO: extract location from parse error!
16+
error: CompileErrorType::Parse(error.error),
17+
location: error.location,
1818
}
1919
}
2020
}
@@ -28,7 +28,7 @@ pub enum CompileErrorType {
2828
/// Expected an expression got a statement
2929
ExpectExpr,
3030
/// Parser error
31-
Parse(ParseError),
31+
Parse(ParseErrorType),
3232
SyntaxError(String),
3333
/// Multiple `*` detected
3434
StarArgs,
@@ -56,10 +56,7 @@ impl fmt::Display for CompileError {
5656
}?;
5757

5858
// Print line number:
59-
match &self.error {
60-
CompileErrorType::Parse(..) => Ok(()),
61-
_ => write!(f, " at line {:?}", self.location.row()),
62-
}
59+
write!(f, " at {}", self.location)
6360
}
6461
}
6562

parser/src/error.rs

Lines changed: 45 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,69 +3,83 @@
33
extern crate lalrpop_util;
44
use self::lalrpop_util::ParseError as InnerError;
55

6-
use crate::lexer::{LexicalError, Location};
6+
use crate::lexer::{LexicalError, LexicalErrorType, Location};
77
use crate::token::Tok;
88

99
use std::error::Error;
1010
use std::fmt;
1111

12-
// A token of type `Tok` was observed, with a span given by the two Location values
13-
type TokSpan = (Location, Tok, Location);
14-
1512
/// Represents an error during parsing
1613
#[derive(Debug, PartialEq)]
17-
pub enum ParseError {
14+
pub struct ParseError {
15+
pub error: ParseErrorType,
16+
pub location: Location,
17+
}
18+
19+
#[derive(Debug, PartialEq)]
20+
pub enum ParseErrorType {
1821
/// Parser encountered an unexpected end of input
19-
EOF(Option<Location>),
22+
EOF,
2023
/// Parser encountered an extra token
21-
ExtraToken(TokSpan),
24+
ExtraToken(Tok),
2225
/// Parser encountered an invalid token
23-
InvalidToken(Location),
26+
InvalidToken,
2427
/// Parser encountered an unexpected token
25-
UnrecognizedToken(TokSpan, Vec<String>),
28+
UnrecognizedToken(Tok, Vec<String>),
2629
/// Maps to `User` type from `lalrpop-util`
27-
Other(LexicalError),
30+
Lexical(LexicalErrorType),
2831
}
2932

3033
/// Convert `lalrpop_util::ParseError` to our internal type
3134
impl From<InnerError<Location, Tok, LexicalError>> for ParseError {
3235
fn from(err: InnerError<Location, Tok, LexicalError>) -> Self {
3336
match err {
3437
// TODO: Are there cases where this isn't an EOF?
35-
InnerError::InvalidToken { location } => ParseError::EOF(Some(location)),
36-
InnerError::ExtraToken { token } => ParseError::ExtraToken(token),
37-
InnerError::User { error } => ParseError::Other(error),
38+
InnerError::InvalidToken { location } => ParseError {
39+
error: ParseErrorType::EOF,
40+
location,
41+
},
42+
InnerError::ExtraToken { token } => ParseError {
43+
error: ParseErrorType::ExtraToken(token.1),
44+
location: token.0,
45+
},
46+
InnerError::User { error } => ParseError {
47+
error: ParseErrorType::Lexical(error.error),
48+
location: error.location,
49+
},
3850
InnerError::UnrecognizedToken { token, expected } => {
3951
match token {
40-
Some(tok) => ParseError::UnrecognizedToken(tok, expected),
52+
Some(tok) => ParseError {
53+
error: ParseErrorType::UnrecognizedToken(tok.1, expected),
54+
location: tok.0,
55+
},
4156
// EOF was observed when it was unexpected
42-
None => ParseError::EOF(None),
57+
None => ParseError {
58+
error: ParseErrorType::EOF,
59+
location: Default::default(),
60+
},
4361
}
4462
}
4563
}
4664
}
4765
}
4866

4967
impl fmt::Display for ParseError {
68+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
69+
write!(f, "{} at {}", self.error, self.location)
70+
}
71+
}
72+
73+
impl fmt::Display for ParseErrorType {
5074
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5175
match *self {
52-
ParseError::EOF(ref location) => {
53-
if let Some(l) = location {
54-
write!(f, "Got unexpected EOF at: {:?}", l)
55-
} else {
56-
write!(f, "Got unexpected EOF")
57-
}
58-
}
59-
ParseError::ExtraToken(ref t_span) => {
60-
write!(f, "Got extraneous token: {:?} at: {:?}", t_span.1, t_span.0)
61-
}
62-
ParseError::InvalidToken(ref location) => {
63-
write!(f, "Got invalid token at: {:?}", location)
64-
}
65-
ParseError::UnrecognizedToken(ref t_span, _) => {
66-
write!(f, "Got unexpected token: {:?} at {:?}", t_span.1, t_span.0)
76+
ParseErrorType::EOF => write!(f, "Got unexpected EOF"),
77+
ParseErrorType::ExtraToken(ref tok) => write!(f, "Got extraneous token: {:?}", tok),
78+
ParseErrorType::InvalidToken => write!(f, "Got invalid token"),
79+
ParseErrorType::UnrecognizedToken(ref tok, _) => {
80+
write!(f, "Got unexpected token: {:?}", tok)
6781
}
68-
ParseError::Other(ref error) => write!(f, "{}", error),
82+
ParseErrorType::Lexical(ref error) => write!(f, "{}", error),
6983
}
7084
}
7185
}

parser/src/lexer.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,23 +75,17 @@ pub enum LexicalErrorType {
7575
OtherError(String),
7676
}
7777

78-
impl fmt::Display for LexicalError {
78+
impl fmt::Display for LexicalErrorType {
7979
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
80-
match self.error {
80+
match *self {
8181
LexicalErrorType::StringError => write!(f, "Got unexpected string"),
8282
LexicalErrorType::UnicodeError => write!(f, "Got unexpected unicode"),
8383
LexicalErrorType::NestingError => write!(f, "Got unexpected nesting"),
8484
LexicalErrorType::UnrecognizedToken { tok } => {
8585
write!(f, "Got unexpected token {}", tok)
8686
}
8787
LexicalErrorType::OtherError(ref msg) => write!(f, "{}", msg),
88-
}?;
89-
write!(
90-
f,
91-
" at line {} column {}",
92-
self.location.row(),
93-
self.location.column()
94-
)
88+
}
9589
}
9690
}
9791

@@ -101,6 +95,12 @@ pub struct Location {
10195
column: usize,
10296
}
10397

98+
impl fmt::Display for Location {
99+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
100+
write!(f, "line {} column {}", self.row, self.column)
101+
}
102+
}
103+
104104
impl Location {
105105
pub fn new(row: usize, column: usize) -> Self {
106106
Location { row, column }

src/main.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ extern crate rustyline;
77

88
use clap::{App, Arg};
99
use rustpython_compiler::{compile, error::CompileError, error::CompileErrorType};
10-
use rustpython_parser::error::ParseError;
10+
use rustpython_parser::error::ParseErrorType;
1111
use rustpython_vm::{
1212
frame::Scope,
1313
import,
@@ -181,7 +181,7 @@ fn shell_exec(vm: &VirtualMachine, source: &str, scope: Scope) -> Result<(), Com
181181
// Don't inject syntax errors for line continuation
182182
Err(
183183
err @ CompileError {
184-
error: CompileErrorType::Parse(ParseError::EOF(_)),
184+
error: CompileErrorType::Parse(ParseErrorType::EOF),
185185
..
186186
},
187187
) => Err(err),
@@ -258,7 +258,7 @@ fn run_shell(vm: &VirtualMachine) -> PyResult {
258258

259259
match shell_exec(vm, &input, vars.clone()) {
260260
Err(CompileError {
261-
error: CompileErrorType::Parse(ParseError::EOF(_)),
261+
error: CompileErrorType::Parse(ParseErrorType::EOF),
262262
..
263263
}) => {
264264
continuing = true;

0 commit comments

Comments
 (0)