use std::io; #[derive(Debug, PartialEq, Eq)] enum Symbol { Number, LeftBracket, RightBracket, Add, Sub, Mul, Div, } #[derive(Debug)] enum ParseError { WrongTokenError { pos: usize }, } fn main() { loop { let user_input = get_user_input().expect("No input"); match tokenize(&user_input) { Ok(tokenized_input) => { for el in &tokenized_input { println!("{:?}", el); } } Err(ParseError::WrongTokenError { pos }) => { for _ in 0..pos { print!("-"); } println!("^"); println!("Syntax Error\n"); } } } } fn get_user_input() -> io::Result { let mut buffer = String::new(); let stdin = io::stdin(); stdin.read_line(&mut buffer)?; Ok(buffer) } #[test] fn try_tokenizing() { let tokenized_input = tokenize("1 + 1").unwrap(); let result = vec![Symbol::Number, Symbol::Add, Symbol::Number]; assert!(tokenized_input == result, "1 + 1 not working"); } fn tokenize(input: &str) -> Result, ParseError> { let mut tokens: Vec = vec![]; for (i, c) in input.chars().enumerate() { match c { ' ' => continue, '(' => tokens.push(Symbol::LeftBracket), ')' => tokens.push(Symbol::RightBracket), '+' => tokens.push(Symbol::Add), '-' => tokens.push(Symbol::Sub), '*' => tokens.push(Symbol::Mul), '/' => tokens.push(Symbol::Div), '0'..='9' => tokens.push(Symbol::Number), '\n' => break, _ => return Err(ParseError::WrongTokenError { pos: i }), } } Ok(tokens) }