1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
extern crate lalrpop_util;
use self::lalrpop_util::ParseError as InnerError;
use crate::lexer::{LexicalError, LexicalErrorType, Location};
use crate::token::Tok;
use std::error::Error;
use std::fmt;
#[derive(Debug, PartialEq)]
pub struct ParseError {
pub error: ParseErrorType,
pub location: Location,
}
#[derive(Debug, PartialEq)]
pub enum ParseErrorType {
EOF,
ExtraToken(Tok),
InvalidToken,
UnrecognizedToken(Tok, Vec<String>),
Lexical(LexicalErrorType),
}
impl From<InnerError<Location, Tok, LexicalError>> for ParseError {
fn from(err: InnerError<Location, Tok, LexicalError>) -> Self {
match err {
InnerError::InvalidToken { location } => ParseError {
error: ParseErrorType::EOF,
location,
},
InnerError::ExtraToken { token } => ParseError {
error: ParseErrorType::ExtraToken(token.1),
location: token.0,
},
InnerError::User { error } => ParseError {
error: ParseErrorType::Lexical(error.error),
location: error.location,
},
InnerError::UnrecognizedToken { token, expected } => {
match token {
Some(tok) => ParseError {
error: ParseErrorType::UnrecognizedToken(tok.1, expected),
location: tok.0,
},
None => ParseError {
error: ParseErrorType::EOF,
location: Default::default(),
},
}
}
}
}
}
impl fmt::Display for ParseError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} at {}", self.error, self.location)
}
}
impl fmt::Display for ParseErrorType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
ParseErrorType::EOF => write!(f, "Got unexpected EOF"),
ParseErrorType::ExtraToken(ref tok) => write!(f, "Got extraneous token: {:?}", tok),
ParseErrorType::InvalidToken => write!(f, "Got invalid token"),
ParseErrorType::UnrecognizedToken(ref tok, _) => {
write!(f, "Got unexpected token: {:?}", tok)
}
ParseErrorType::Lexical(ref error) => write!(f, "{}", error),
}
}
}
impl Error for ParseError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
None
}
}