Select Git revision
Quickstart.md
main2.rs 4.42 KiB
extern crate nom;
use nom::combinator::map_res;
use nom::{
branch::alt,
bytes::complete::tag,
character::complete::{digit1, multispace0},
combinator::map,
error::{context, VerboseError, VerboseErrorKind},
sequence::{preceded, tuple},
IResult,
};
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Op {
Add,
Sub,
Mul,
Div,
Pow,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Expr {
Num(i32),
BinOp(Box<Expr>, Op, Box<Expr>),
}
// // deep cloning (is it necessary)
// impl Clone for Expr {
// fn clone(&self) -> Expr {
// match self {
// Expr::BinOp(l, op, r) => Expr::BinOp (
// l.clone(), *op, r.clone()
// ),
// Expr::Num(i) => Expr::Num(*i)
// }
// }
// }
pub fn parse_i32(i: &str) -> IResult<&str, Expr> {
map(digit1, |digit_str: &str| {
Expr::Num(digit_str.parse::<i32>().unwrap())
})(i)
}
fn parse_op(i: &str) -> IResult<&str, Op> {
alt((
map(tag("+"), |_| Op::Add),
map(tag("-"), |_| Op::Sub),
map(tag("*"), |_| Op::Mul),
map(tag("/"), |_| Op::Div),
map(tag("^"), |_| Op::Pow),
))(i)
}
fn parse_expr(i: &str) -> IResult<&str, Expr> {
preceded(
multispace0,
alt((
map(
tuple((parse_i32, preceded(multispace0, parse_op), parse_expr)),
|(l, op, r)| Expr::BinOp(Box::new(l), op, Box::new(r)),
),
parse_i32,
)),
)(i)
}
fn math_expr(e: &Expr) -> String {