what type of argument to supply for i.err()?
dckc opened this issue · 4 comments
What do I give as the argument?
I can't figure out what to use in place of 0:
fn expr(i: Input<u8>) -> U8Result<ExprRef> {
or(i,
literal(i),
// TODO: all the other sorts of Expr
i.err(0)) // <- here
}
I can't understand the diagnostics:
cargo test
Compiling monte-rs v0.1.0 (file:///home/connolly/projects/monte-rs)
src/mast.rs:24:5: 24:7 error: the trait `core::ops::FnOnce<(chomp::input::Input<'_, u8>,)>` is not implemented for the type `chomp::parse_result::ParseResult<'_, u8, Box<alloc::rc::Rc<kernel::Expr>>, chomp::parsers::Error<u8>>` [E0277]
src/mast.rs:24 or(i,
^~
src/mast.rs:24:5: 24:7 help: run `rustc --explain E0277` to see a detailed explanation
src/mast.rs:24:5: 24:7 note: required by `chomp::combinators::or`
src/mast.rs:24:5: 24:7 error: the trait `core::ops::FnOnce<(chomp::input::Input<'_, u8>,)>` is not implemented for the type `chomp::parse_result::ParseResult<'_, u8, _, _>` [E0277]
src/mast.rs:24 or(i,
^~
src/mast.rs:24:5: 24:7 help: run `rustc --explain E0277` to see a detailed explanation
src/mast.rs:24:5: 24:7 note: required by `chomp::combinators::or`
src/mast.rs:24:5: 24:7 error: the trait `core::ops::FnOnce<(chomp::input::Input<'_, u8>,)>` is not implemented for the type `chomp::parse_result::ParseResult<'_, u8, Box<alloc::rc::Rc<kernel::Expr>>, chomp::parsers::Error<u8>>` [E0277]
src/mast.rs:24 or(i,
^~
src/mast.rs:24:5: 24:7 help: run `rustc --explain E0277` to see a detailed explanation
src/mast.rs:24:5: 24:7 note: required by `chomp::combinators::or`
src/mast.rs:24:5: 24:7 error: the trait `core::ops::FnOnce<(chomp::input::Input<'_, u8>,)>` is not implemented for the type `chomp::parse_result::ParseResult<'_, u8, _, _>` [E0277]
src/mast.rs:24 or(i,
^~
src/mast.rs:24:5: 24:7 help: run `rustc --explain E0277` to see a detailed explanation
src/mast.rs:24:5: 24:7 note: required by `chomp::combinators::or`
error: aborting due to 2 previous errors
U8Result is an alias for ParseResult<u8, T, Error<u8>>
. The error type used by U8Result
is parsers::Error
, use Error::new
to create an "unexpected error" to return.
If that is not good enough (ie. you need something more verbose), declare your own error type and implement From<Error>
for it:
enum MyError {
ParseError(chomp::Error<u8>),
ExpectedExpression,
// ...
}
impl From<chomp::Error<u8>> for MyError {
fn from(e: chomp::Error<u8>) -> Self {
MyError::ParseError(e)
}
}
bind
(and therefore also then
and usages of the parse!
macro) will automatically convert it for you if you chain anything. If it is just a plain or
combinator which has been stacked, use map_err(From::from)
on the parse error(s).
I tried to use Error:new
, but I couldn't get it to work. I'd appreciate an example.
Likewise map_err
; it's not clear to me how that would work.
I think I get it now.
Just to make it clear for anyone else reading this, it would be one of these:
fn expr(i: Input<u8>) -> U8Result<ExprRef> {
or(i,
|i literal(i),
// TODO: all the other sorts of Expr
|i| i.err(Error::new())) // <- here
}
This would yield an unexpected error at the start of the attempt to match an expr
. Another alternative is to just skip the error part completely, letting the last error from the last attempted parser bubble up. The downside with this is that it can look a bit odd when an error occurs further in than it really is.
enum MyError {
ParseError(chomp::Error<u8>),
ExpectedExpression,
// ...
}
impl From<chomp::Error<u8>> for MyError {
fn from(e: chomp::Error<u8>) -> Self {
MyError::ParseError(e)
}
}
fn expr(i: Input<u8>) -> ParseResult<u8, ExprRef, MyError> {
// We use two backtracks here to be able to use From::from once:
or(i,
|i| or(i, literal,
|i| or(i, constant,
|i| or(i, operator, ...)))
.map_err(From::from),
|i| i.err(MyError::ExpectedExpression))
}
The code above has the benefit of being very flexible when it comes to the errors, it can store plain parse errors as well as just indicating that an expression was expected (this could then be extended so that all of those errors are more verbose, exactly what part failed in parsing an expression).