Select Git revision
main_span_expr_custom_err2.rs
Forked from
Per Lindgren / D7050E
Source project has a limited visibility.
main_span_expr_custom_err2.rs 4.17 KiB
extern crate nom;
use nom::{
branch::alt,
bytes::complete::tag,
character::complete::{digit1, multispace0},
combinator::map,
error,
sequence::{preceded, tuple},
Err,
};
use nom_locate::LocatedSpan;
type Span<'a> = LocatedSpan<&'a str>;
#[derive(Debug)]
pub struct Error<'a>(Span<'a>, Option<Span<'a>>, ErrorKind);
type IResult<'a, I, O, E = Error<'a>> = Result<(I, O), Err<E>>;
impl<'a> error::ParseError<Span<'a>> for Error<'a> {
fn from_error_kind(input: Span<'a>, kind: error::ErrorKind) -> Self {
Error(input, None, ErrorKind::Nom(kind))
}
fn append(_: Span<'a>, _: error::ErrorKind, other: Self) -> Self {
other
}
}
#[derive(Debug)]
enum ErrorKind {
ParseIntError(std::num::ParseIntError),
Nom(error::ErrorKind),
}
#[derive(Debug, PartialEq)]
pub enum Op {
Add,
Sub,
}
type SpanOp<'a> = (Span<'a>, Op);
fn parse_op(i: Span) -> IResult<Span, SpanOp> {
alt((
map(tag("+"), |s| (s, Op::Add)),
map(tag("-"), |s| (s, Op::Sub)),
))(i)
}
#[derive(Debug, PartialEq)]
pub enum Expr<'a> {
Num(i32),
Num64(i64),
BinOp(Box<SpanExpr<'a>>, SpanOp<'a>, Box<SpanExpr<'a>>),
}
type SpanExpr<'a> = (Span<'a>, Expr<'a>);
pub fn parse_i32<'a>(i: Span<'a>) -> IResult<Span<'a>, SpanExpr> {
let (i, digits) = digit1(i)?;
match digits.fragment.parse() {
Ok(int) => Ok((i, (digits, Expr::Num(int)))),
Err(e) => Err(Err::Error(Error(
i,
Some(digits),
ErrorKind::ParseIntError(e),
))),
}