Skip to content
Snippets Groups Projects
Select Git revision
  • cc015e73c6621484b54aa08d2b24f0b3c90a8bc5
  • master default protected
2 results

Quickstart.md

Blame
  • 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 {