72 lines
1.8 KiB
Rust
72 lines
1.8 KiB
Rust
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<String> {
|
|
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<Vec<Symbol>, ParseError> {
|
|
let mut tokens: Vec<Symbol> = 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)
|
|
}
|