First commit
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
use winnow::Parser;
|
||||
use winnow::ascii::multispace0;
|
||||
use winnow::combinator::{Infix, Prefix, peek};
|
||||
use winnow::combinator::{delimited, dispatch, expression, fail};
|
||||
use winnow::error::ContextError;
|
||||
use winnow::token::any;
|
||||
|
||||
use crate::binary_repr::parse_binary_repr;
|
||||
use crate::expr::{BinOp, Expr, UnaryOp};
|
||||
|
||||
pub fn parser<'i>(size: usize) -> impl Parser<&'i str, Expr, ContextError> {
|
||||
move |i: &mut &str| {
|
||||
use Infix::Left;
|
||||
expression(delimited(
|
||||
multispace0,
|
||||
dispatch! {peek(any);
|
||||
'(' => delimited('(', parser(size).map(|e| Expr::Group(Box::new(e))), ')'),
|
||||
_ => parse_binary_repr(size).map(Expr::Constant),
|
||||
|
||||
},
|
||||
multispace0,
|
||||
))
|
||||
.prefix(delimited(
|
||||
multispace0,
|
||||
dispatch! {any;
|
||||
'-' => Prefix(12, |_, a| Ok(Expr::UnaryOp(UnaryOp::Neg, Box::new(a)))),
|
||||
'!' => Prefix(12, |_, a| Ok(Expr::UnaryOp(UnaryOp::Not, Box::new(a)))),
|
||||
_ => fail,
|
||||
},
|
||||
multispace0,
|
||||
))
|
||||
.infix(delimited(
|
||||
multispace0,
|
||||
dispatch! {any;
|
||||
'+' => Left(5, |_, a, b| Ok(Expr::BinaryOp(Box::new(a), BinOp::Plus, Box::new(b)))),
|
||||
'-' => Left(5, |_, a, b| Ok(Expr::BinaryOp(Box::new(a), BinOp::Sub, Box::new(b)))),
|
||||
'*' => Left(7, |_, a, b| Ok(Expr::BinaryOp(Box::new(a), BinOp::Mul, Box::new(b)))),
|
||||
'/' => Left(7, |_, a, b| Ok(Expr::BinaryOp(Box::new(a), BinOp::Div, Box::new(b)))),
|
||||
_ => fail,
|
||||
},
|
||||
multispace0,
|
||||
))
|
||||
.parse_next(i)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user