mirror of
https://github.com/fluencelabs/lalrpop
synced 2025-03-16 17:00:53 +00:00
Add utility methods to ParseError
Add three methods .map_loc(), .map_tok() and .map_err() that transform the locations, tokens and user error values inside the ParseError.
This commit is contained in:
parent
08bb4c98b9
commit
7bdb7126b0
@ -154,6 +154,26 @@ fn expr_intern_tok_test_err() {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn expr_intern_tok_display_err() {
|
||||
let expr = "(1+\n(2++3))";
|
||||
let result = expr_intern_tok::parse_Expr(1, expr);
|
||||
let err : lalrpop_util::ParseError<usize, (usize, &str),()>
|
||||
= result.expect_err("expected a syntax error");
|
||||
|
||||
// The problem is that (usize,&str) and () do not implement fmt::Display,
|
||||
// so neither does the ParseError.
|
||||
// We can fix that by rewriting them to something else, such as a string.
|
||||
let disp = err.map_tok(|(_,t)|t).map_err(|_| "error");
|
||||
assert!(disp.to_string().contains("Unrecognized token +"));
|
||||
|
||||
// We can even convert the locations to a line number
|
||||
let line_based = disp.map_loc(|offset| {
|
||||
format!("line {}", expr[0..offset].lines().count())
|
||||
});
|
||||
assert!(line_based.to_string().contains("line 2"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn expr_lifetime_tok1() {
|
||||
// the problem here was that we were improperly pruning the 'input from the
|
||||
|
@ -36,6 +36,34 @@ pub enum ParseError<L,T,E> {
|
||||
},
|
||||
}
|
||||
|
||||
impl<L, T, E> ParseError<L, T, E> {
|
||||
fn map_intern<FL,LL,FT,TT,FE,EE>(self, loc_op: FL, tok_op: FT, err_op: FE) -> ParseError<LL,TT,EE>
|
||||
where FL: Fn(L) -> LL,
|
||||
FT: Fn(T) -> TT,
|
||||
FE: Fn(E) -> EE
|
||||
{
|
||||
let maptok = |(s,t,e) : (L,T,L)| (loc_op(s), tok_op(t), loc_op(e));
|
||||
match self {
|
||||
ParseError::InvalidToken { location } => ParseError::InvalidToken { location: loc_op(location) },
|
||||
ParseError::UnrecognizedToken { token, expected } => ParseError::UnrecognizedToken { token: token.map(maptok), expected: expected },
|
||||
ParseError::ExtraToken { token } => ParseError::ExtraToken { token: maptok(token) },
|
||||
ParseError::User { error } => ParseError::User { error: err_op(error) }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn map_loc<F,LL>(self, op: F) -> ParseError<LL, T, E> where F: Fn(L) -> LL {
|
||||
self.map_intern(op, |x|x, |x|x)
|
||||
}
|
||||
|
||||
pub fn map_tok<F,TT>(self, op: F) -> ParseError<L, TT, E> where F: Fn(T) -> TT {
|
||||
self.map_intern(|x|x, op, |x|x)
|
||||
}
|
||||
|
||||
pub fn map_err<F,EE>(self, op: F) -> ParseError<L, T, EE> where F: Fn(E) -> EE {
|
||||
self.map_intern(|x|x, |x|x, op)
|
||||
}
|
||||
}
|
||||
|
||||
impl<L, T, E> fmt::Display for ParseError<L, T, E>
|
||||
where L: fmt::Display,
|
||||
T: fmt::Display,
|
||||
|
Loading…
x
Reference in New Issue
Block a user