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

Project_suggestions.md

Blame
  • main.rs 1.25 KiB
    extern crate nom;
    
    use nom::combinator::map_res;
    use nom::{
        branch::alt,
        bytes::complete::tag,
        character::complete::{digit1, multispace0},
        combinator::map,
        error::{VerboseError, VerboseErrorKind},
        map_res,
        sequence::{preceded, tuple},
        IResult,
    };
    
    #[derive(Debug, PartialEq)]
    pub enum Op {
        Add,
    }
    
    #[derive(Debug, PartialEq)]
    pub enum Expr {
        Num(i32),
        BinOp(Box<Expr>, Op, Box<Expr>),
    }
    
    pub fn parse_i32(i: &str) -> IResult<&str, Expr, VerboseError<&str>> {
        map_res(digit1, |digit_str: &str| match digit_str.parse::<i32>() {
            Err(e) => Err(VerboseError {
                errors: vec![(digit_str, VerboseErrorKind::Context("not a 32-bit integer"))],
            }),
            Ok(x) => Ok(Expr::Num(x)),
        })(i)
    }
    
    fn parse_expr(input: &str) -> IResult<&str, Expr, VerboseError<&str>> {
        preceded(
            multispace0,
            alt((
                map(
                    tuple((parse_i32, preceded(multispace0, tag("+")), parse_expr)),
                    |(l, _, r)| Expr::BinOp(Box::new(l), Op::Add, Box::new(r)),
                ),
                parse_i32,
            )),
        )(input)
    }
    
    fn main() {
        println!("{:?}", parse_expr("1"));
        println!("{:?}", parse_expr("1+1a"));
        println!("{:?}", parse_expr("11111111111111111111111111"));
    }